排序--归并排序

本文介绍了归并排序算法的实现原理及过程,通过C#、C和C++三种语言的示例代码展示了如何进行分治与合并操作。归并排序的时间复杂度为O(nlogn),是一种稳定排序算法。

归并排序的时间复杂度是 O( nlogn ) ,归并排序比较占用内存,但是是一个稳定的排序算法。


C# 版

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharp
{
    class Program
    {
        // 合并
        static void merge( int[] arr, int l, int m, int r ) 
        {
            int left_size = m - l;
            int right_size = r - m + 1;
            int[] left_arr = new int[left_size];
            int[] right_arr = new int[right_size];

            // 1. 把数据填入到左子数组里
            for (int t = l; t < m; ++t)
            {
                left_arr[t - l] = arr[t];
            }

            // 2. 把数据填入到右子数组里
            for (int t = m; t <= r; ++t)
            {
                right_arr[t - m] = arr[t];
            }

            // 3. 把左右子数组合并到大数组里
            int i = 0 ;
            int j = 0 ;
            int k = l ;
            while ( i < left_size && j < right_size )
            {
                if ( left_arr[i] < right_arr[j] )
                {
                    arr[k] = left_arr[i];
                    ++i;
                    ++k;
                }
                else
                {
                    arr[k] = right_arr[j];
                    ++j;
                    ++k;
                }
            }

            while ( i < left_size )
            {
                arr[k] = left_arr[i];
                ++i;
                ++k;
            }

            while ( j < right_size )
            {
                arr[k] = right_arr[j];
                ++j;
                ++k;
            }
        }

        // 分治
        static void MergeSort( int[] arr, int l, int r )
        {
            if ( l == r )
            {
                return; // 递归退出条件:左边等于右边
            }

            int m = (l + r) / 2;
            MergeSort(arr, l, m); // 细分数组
            MergeSort(arr, m + 1, r); // 细分数组
            merge(arr, l, m + 1, r);
        }
        static void Main(string[] args)
        {
            int[] arr = { 6, 8, 10, 9, 4, 5, 2, 7 };
            MergeSort(arr, 0, arr.Length - 1);

            for ( int i = 0; i < arr.Length; ++ i )
            {
                Console.Write(arr[i] + ", ");
            }

            Console.ReadLine();
        }
    }
}



C 版

// c.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <malloc.h>

// 合并
void merge(int arr[], int l, int m, int r)
{
	int left_size = m - l ;
	int right_size = r - m + 1 ;
	int* left_arr = (int*)malloc(left_size * sizeof(int));
	int* right_arr = (int*)malloc(right_size * sizeof(int));

	// 1. 把数据填入到左子数组里
	for (int i = l; i < m; ++i)
	{
		left_arr[i - l] = arr[i] ;
	}

	// 2. 把数据填入到右子数组里
	for (int i = m; i <= r; ++i)
	{
		right_arr[i - m] = arr[i] ;
	}

	// 3. 把左右子数组合并到大数组里
	int i = 0 ;
	int j = 0 ;
	int k = l ;
	while (i < left_size && j < right_size)
	{
		if (left_arr[i] < right_arr[j])
		{
			arr[k] = left_arr[i] ;
			++i ;
			++k ;
		}
		else
		{
			arr[k] = right_arr[j] ;
			++j ;
			++k ;
		}
	}

	while (i < left_size)
	{
		arr[k] = left_arr[i] ;
		++i ;
		++k ;
	}

	while (j < right_size)
	{
		arr[k] = right_arr[j] ;
		++j ;
		++k ;
	}
}

// 分治
void MergeSort(int arr[], int l, int r)
{
	if (l == r)
	{
		return ; // 递归退出条件:左边等于右边
	}

	int m = (l + r) / 2 ;
	MergeSort(arr, l, m) ; // 细分数组
	MergeSort(arr, m + 1, r) ; // 细分数组
	merge(arr, l, m + 1, r) ;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int arr[] = {6, 8, 10, 9, 4, 5, 2, 7};
	int length = 7;
	MergeSort(arr, 0, length);

	for (int i = 0; i < length; ++i)
	{
		printf("%d, ", arr[i]);
	}

	getchar();
	return 0;
}



C++ 版

// c++.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <vector>
#include <iostream>
using namespace::std;

void merge(vector<int>& vec, int l, int m, int r)
{
	int left_size = m - l ;
	int right_size = r - m + 1 ;
	vector<int> left_vec ;
	vector<int> right_vec ;

	for (int i = l; i < m; ++i)
	{
		left_vec.push_back(vec[i]);
	}

	for (int i = m; i <= r; ++i)
	{
		right_vec.push_back(vec[i]);
	}

	int i = 0 ;
	int j = 0 ;
	int k = l ;
	while (i < left_size && j < right_size)
	{
		if (left_vec[i] < right_vec[j])
		{
			vec[k] = left_vec[i] ;
			++i ;
			++k ;
		}
		else
		{
			vec[k] = right_vec[j] ;
			++j ;
			++k ;
		}
	}

	while (i < left_size)
	{
		vec[k] = left_vec[i] ;
		++i ;
		++k ;
	}
	while (j < right_size)
	{
		vec[k] = right_vec[j] ;
		++j ;
		++k ;
	}
}

void MergeSort(vector<int>& vec,int l, int r)
{
	if (l == r)
	{
		return ;
	}

	int m = (l + r) / 2 ;
	MergeSort(vec, l, m) ;
	MergeSort(vec, m + 1, r) ;
	merge(vec, l, m + 1, r) ;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int arr[] = {6, 8, 10, 9, 4, 5, 2, 7};
	vector<int> vec(arr, arr + 7);
	MergeSort(vec, 0, vec.size() - 1);

	for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it)
	{
		std::cout << *it << ", " ;
	}

	system("pause");
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值