• 从排序开始(三)归并排序


    归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。


    归并操作的过程如下:

    1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

    2.设定两个指针,最初位置分别为两个已经排序序列的起始位置

    3.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

    4.重复步骤3直到某一指针达到序列尾

    5.将另一序列剩下的所有元素直接复制到合并序列尾


    简单地说,归并排序就是将序列不断地划分,直到每个序列只有一个元素(一个元素的序列肯定是有序的),然后这些有序序列不断归并,合成新的有序序列,最后,归并成全部有序的序列。


    这幅 Wiki 的图很直观地解释了归并排序:

    Merge-sort-example-300px.gif


    最差时间复杂度  O(n logn)
    最优时间复杂度  O(n)
    平均时间复杂度  O(n logn)

    稳定性:稳定


    实现:

    #include <iostream>
    
    using namespace std;
    
    //归并操作,将有两个个有序数列 num[start...mid] 和 num[mid...end] 归并并。
    //归并至 sorted 序列,然后复制回原数组
    void merge(int num[], int start, int mid, int end, int sorted[])
    {
    	int i = start, j = mid + 1;
    	int m = mid,   n = end;
    	int k = 0;
    	
    	//每次比较两个元素,直到某个序列到达末尾
    	while (i <= m && j <= n)
    	{
    		if (num[i] <= num[j])
    			sorted[k++] = num[i++];
    		else
    			sorted[k++] = num[j++];
    	}
    	
    	//将序列中剩余元素直接复制到 sorted 序列尾
    	while (i <= m)
    		sorted[k++] = num[i++];
    	
    	while (j <= n)
    		sorted[k++] = num[j++];
    	
    	//将排序好的序列写回原数组
    	for (i = 0; i < k; i++)
    		num[start + i] = sorted[i];
    }
    
    void mergesort(int a[], int start, int end, int sorted[])
    {
    	if (start < end)
    	{
    		//进行分治
    		int mid = (start + end) / 2;
    		mergesort(a, start, mid, sorted);    
    		mergesort(a, mid + 1, end, sorted); 
    		merge(a, start, mid, end, sorted); 
    	}
    }
    
    bool MergeSort(int num[], int n)
    {
    	int *p = new int[n];
    	if (p == NULL)
    		return false;
    	mergesort(num, 0, n - 1, p);
    	delete[] p;
    	return true;
    }
    
    //简单测试,建议数据不要太大,那是在刷屏啊 o(╯□╰)o
    int main()
    {
    	int n;
    	//测试 n 个随机数的排序
    	while(cin>>n)
    	{
    		int *p = new int[n];
    		if (!p)
    		{
    			cout<<"Failed..."<<endl;
    			continue;
    		}
    		for(int i=0;i<n;++i)
    			p[i] = rand();
    		bool flag = MergeSort(p,n);
    		if(!flag)
    		{
    			cout<<"Failed..."<<endl;
    			continue;
    		}
    		for(int i=0;i<n;++i)
    			cout<<p[i]<<' ';
    		cout<<endl;
    		delete []p;
    	}
    	return 0;
    }



  • 相关阅读:
    WPF DataGrid根据内容设置行颜色
    wpf: DataGridTextColumn 数字格式显示,编辑时取消格式(StringFormat)
    关于wpf,datagrid,双向数据绑定用法解决方案
    AddTransient、AddSingleton、AddScoped 三者都应该在什么场景下使用
    Fetch API 使用 fatch 函数调用 .netcore WebApi接口报错:Failed to fetch
    ASP.NET Core 中使用Session会话
    利用 Google Chart API 生成二维码大小不一致
    Razor Page 文件
    asp.net core 的 razor pages 如何使用ajax调用后台方法
    asp.net core 发布到iis session无法传递的问题
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3328952.html
Copyright © 2020-2023  润新知