归并排序
归并是对于元素的集合,用指定个数的元素排序,然后进行合并排序的一种方式。
我们这里主要是研究的两两合并的方式,也称为二路归并。
下面来看看推导过程:
设有数组int data[8]={9,1,15,8,7,3,6,4};
1,此时元组为[{9} {1} {15} {8} {7} {3} {6} {4}],把元素分为2个一组,然后排序则有{1,9} {8,15}{3,7}{4,6}
2,此时发现元组大于1,则继续2个一组归并,得到{1,8,9,15},{3,4,6,7}
3,此时元组仍然大于1,则继续2个一组归并,得到{1,3,4,6,7,8,9,15}。此时元组为1,结束归并,得到最终结果。
所以,其实归并排序的过程,就分为2个步骤:单元组内排序,2个单元组合并.
来看代码:
//单个数组内元素排序 void arraySort(int *data,const int length) { int* temp = new int[length];//存放归并后的数据 int mid=length/2; int index1=0; int index2=mid; int i; for (i=0;i<=mid&&index1<length&&index2<length;i++)// { if (data[index1]<data[index2])//第一个序列元素比第二个序列的元素要小,向前 temp[i]=data[index1++]; else if (data[index1>data[index2]])//类似 temp[i]=data[index2++]; } //把剩余的元素加在数组里 if (index1!=mid) { for (;index1<mid;index1++) { temp[i++]=data[index1]; } } else if (index2!=length) { for (;index2<length;index2++) { temp[i++]=data[index2]; } } //数组拷贝 for (int j=0;j<length;j++) { data[j]=temp[j]; } delete []temp; temp=NULL; } //两个数组进行合并 void merge(int *data,int start,int end) { int* temp = new int[end-start+1]; for (int i=start;i<=end;i++) { temp[i-start]=data[i]; }//把需要归并的数组拷贝出来 arraySort(temp,end-start+1);//排序 for (int i=start;i<=end;i++) { data[i]=temp[i-start];//使元素组有序 } delete []temp; temp=NULL; } //归并排序 void mergeSort(int *data,const int length) { for (int i=2;i<=length;i*=2)//两两归并 { for (int j=i;j<=length;j+=i)//j指在数组中需要归并的元素的位置 { merge(data,j-i,j-1); } } }//当然了还可以用递归。。。
上面的代码还可以进行优化,比如把排序和归并放在一起,作为一个函数。但是为了更好的理解过程,故写成如上形式。
优化代码请看:http://zh.wikipedia.org/wiki/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F