shell排序
void ShellSort(int *a)
{
int increment = MAXSIZE;
while (increment > 1) {
increment = increment / 3 + 1;
for (int i = increment; i < MAXSIZE; i++) {
if(a[i] < a[i - increment]){
int temp = a[i];
int j = i - increment;
for (; j >= 0 && temp < a[j]; j-=increment) {
a[j + increment] = a[j];
}
a[j + increment] = temp;
}
}
}
}
时间复杂度 :O(nlogn ~ n^2)
堆排序
堆是具有下列性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆
堆排序的基本思想:将待排序的序列结构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根结点。将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的N-1个序列重新构造成一个堆,这样就会得到n个元素中的次小值。如此反复执行,便能得到一个有序序列了。
void HeapAdjust(int *a, int s, int length)
{
int temp;
temp = a[s-1];
int j = 2 * s;
for (; j <= length; j *= 2) {
if(j < length && a[j-1] < a[j])
j++;
if(temp >= a[j-1]) break;
a[s-1] = a[j-1];
s = j;
}
a[s-1] = temp;
}
void heapSort(int *a)
{
for (int i = MAXSIZE / 2; i > 0; i--) {
HeapAdjust(a, i, MAXSIZE);
}
for (int i = MAXSIZE ; i > 0 ; i--) {
swap(&a[0], &a[i - 1]);
HeapAdjust(a, 1, i - 1);
}
}
时间复杂度:O(nlogn)
并归排序
并归排序的原理是:假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两并归,得到[n/2]([x]表示不小于x的最小整数)个长度为2或1的有序子序,然后两两并归,······,如此反复,直到得到一个长度为n的有序序列为止,这种排序方法称为2路并归排序
时间复杂度:O(nlogn)
快速排序
快速排序的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。
int Partition(int *a, int low, int high)
{
int pivotkey;
pivotkey = a[low];
while (low < high) {
while (low < high && a[high] >= pivotkey)
high--;
swap(&a[low], &a[high]);
while (low < high && a[low] <= pivotkey)
low++;
swap(&a[low], &a[high]);
}
return low;
}
void QSort(int *a, int low, int high)
{
int pivot;
if(low < high){
pivot = Partition(a, low, high);
QSort(a, low, pivot - 1);
QSort(a, pivot+1, high);
}
}
void QuickSort(int *a)
{
QSort(a,0,MAXSIZE-1);
}
时间复杂度:nlogn