归并排序
void MergeSort(Type a[], int left, int right)
{
if (left<right) {//至少有2个元素
int i=(left+right)/2; //取中点
mergeSort(a, left, i);
mergeSort(a, i+1, right);
merge(a, b, left, i, right); //合并到数组b
copy(a, b, left, right); //复制回数组a
}
}
该排序算法主要是利用了分治的思想将大问题转变为多个小问题去解决
该函数的每一次递归中将一个数组从中间分为两部分再分别对于这两部分分别调用自身进行递归,
结束后再将所得的两个排好序的数组合并为一个数组
该算法的复杂度为n*logn;具有稳定性
在将两个数组合并的过程中可以直接使用两个指针指向两个数组的左端,两个指针指向的数进行比较,较小的一端加入新数组,然后该指针右移。
#include <iostream>
using namespace std;
void Merge(int Array[], int begin, int middle, int end){
int n1 = middle - begin;
int n2 = end - middle;
int *left = new int[n1];
int *right = new int[n2];
for(int i = 0; i < n1; i++)
left[i] = Array[begin + i];
for(int i = 0; i < n2; i++)
right[i] = Array[middle + i];
int i = 0, j = 0, key;
for(key = begin; key < end; key++){
if(i < n1 && left[i] <= right[j])
Array[key] = left[i++];
else if(j < n2 && left[i] >= right[j])
Array[key] = right[j++];
else if(i == n1 && j < n2){
Array[key] = right[j++];
}
else if(j == n2 && i < n1){
Array[key] = left[i++];
}
}
}
void MergeSort(int Array[], int begin, int end){
if(begin + 1 < end){
int middle = (end + begin) / 2;
MergeSort(Array, begin, middle);
MergeSort(Array, middle, end);
Merge(Array, begin, middle, end);
}
}
int main(int argc, char** argv){
int n;
cin>>n;
int Array[n];
for(int i = 0; i < n; i++)
cin>>Array[i];
MergeSort(Array, 0, n);
for(int i = 0; i < n; i++)
cout<<Array[i]<<" ";
cout<<endl;
return 0;
}
快速排序
在快速排序中,记录的比较和交换是从两端向中间 进行的,关键字较大的记录一次就能交换到后面单 元,关键字较小的记录一次就能交换到前面单元, 记录每次移动的距离较大,因而总的比较和移动次 数较少。
template<class Type>
void QuickSort (Type a[], int p, int r)
{
if (p<r) {
int q=Partition(a,p,r);
QuickSort (a,p,q-1); //对左半段排序
QuickSort (a,q+1,r); //对右半段排序
}
}
该算法的平均复杂度为n*logn,但是不具备稳定性
template<class Type>
void QuickSort (Type a[], int p, int r)
{
if (p<r) {
int q=Partition(a,p,r);
QuickSort (a,p,q-1); //对左半段排序
QuickSort (a,q+1,r); //对右半段排序
}
}
int Partition (Type a[], int p, int r)
{
int i = p, j = r + 1;
Type x=a[p];
// Swap elements less than x to the left field
// Swap elements greater than x to the right field
while (true) {
while (a[++i] <x&&i<r);
while (a[- -j] >x);
if (i >= j) break;
Swap(a[i], a[j]);
}
a[p] = a[j];
a[j] = x;
return j;
}