排序算法总结--归并排序算法

归并排序算法

在排序算法中快速排序的效率是非常高的,但是还有种排序算法的效率可以与之媲美,那就是归并排序;归并排序和快速排序有那么点异曲同工之妙,快速排序:是先把数组粗略的排序成两个子数组,然后递归再粗略分两个子数组,直到子数组里面只有一个元素,那么就自然排好序了,可以总结为先排序再递归;归并排序:先什么都不管,把数组分为两个子数组,一直递归把数组划分为两个子数组,直到数组里只有一个元素,这时候才开始排序,让两个数组间排好序,依次按照递归的返回来把两个数组进行排好序,到最后就可以把整个数组排好序;

归并排序时的时间复杂度为O(nlgn) 其主要思想是分治法(divide and conquer),分就是要将n个元素的序列划分为两个序列,再将两个序列划分为4个序列,直到每个序列只有一个元素,最后,再将两个有序序列归并成一个有序的序列。例如两个序列:

要归并成一个有序的序列,按照我们常规的方法,我们每次从两个列表开头元素选取较小的一个,直到某一个列表到达底部,再将另一个剩下部分顺序取出。其实如果将每个元素最后添加一个最大值,则无需判断是否达到列表尽头。

算法的理解其实可以借助下面这个图:

对于原始的数组2,1,3,8,5,7,6,4,10,在整个过程执行的是顺序是途中红色编号1-20。虽然我们描述中说的是程序先分解,再归并,但实际过程是一边分解一边归并,前半部分分先排好序,后半部分再拍好,最后整个归并为一个完整的序列,途中的merge过程它所在层的两个序列的merge过程:下图展示了每个merge过程对作用于数组的哪部分(红色)。

整个过程就像一个动态的树,执行顺序就是对树的先序遍历顺序。

 #include <iostream>
 
 using namespace std;
 
 #define LEN 12 
 int *tmp = new int[LEN]; //注意tmp数组从递归开始至递归结束都是同一个数组,所以只能设置成全局变量,如果在函数内设置则会错误 
 
 // 打印数组  
 void print_array(int *array)  
 {  
     int index = 0;  
     printf("\narray:\n");  
     for (; index < 12; index++){  
         printf(" %d, ", *(array + index));  
     }  
     printf("\n");   
 }  
 
 // 把两个有序的数组排序成一个数组  
 void mergeSortArray(int array[],int start,int mid,int end)
 {
 	 int startFirst = start;
 	 int startLast = mid;
	 int endFirst = mid + 1;	
	 int endLast = end;
	 //int len = end - start + 1; //注意tmp数组从递归开始至递归结束都是同一个数组,所以只能设置成全局变量,如果在函数内设置则会错误 
	 //int tmp[len] = {};
	 int index = start;
	 
	 while((startFirst <= startLast) && (endFirst <= endLast))
	 {
	 	if(array[startFirst] <= array[endFirst])
	 		tmp[index++] = array[startFirst++];
	 	else
		 	tmp[index++] = array[endFirst++];
	 }
	 
	 while(startFirst <= startLast)
	 {
	 	tmp[index++] = array[startFirst++];
	 }
	 
	 while(endFirst <= endLast)
	 {
	 	tmp[index++] = array[endFirst++];
	 }
	 
	 for(startFirst = start; startFirst <= end; startFirst++)
	 {
	 	array[startFirst] = tmp[startFirst];
	 }
 }
 
 void mergeSort(int array[], int start, int end)
 {
 	if(start < end)
 	{
 		int mid = (start + end) / 2;
 		mergeSort(array,start,mid);
		mergeSort(array,mid+1,end);
		mergeSortArray(array,start,mid,end);	
 	}
 	
 }
 int main(void)  
 {  
     int array[LEN] = {2, 1, 4, 0, 12, 520, 2, 9, 5, 3, 13, 14};  
     print_array(array);  
     mergeSort(array, 0, LEN - 1);  
     print_array(array);  
     return 0;  
 } 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值