//快速排序
//排序思想:
//1.從數列中挑出一個元素,稱爲 “基準”(pivot),
//2.重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分區退出之後,該基準就處於數列的中間位置。這個稱爲分區(partition)操作。
//3.遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序
int PartSort(int* a, int left, int right) { int key = a[right];//找最右邊一個爲基準 int begin = left; int end = right - 1; while (begin < end) { while (begin < end&&a[begin] <= key)//當找到大於基準數時停 { ++begin; } while (begin < end&&a[end] >= key)//當找到小於基準數時停 { --end; } if (begin < end) { swap(a[begin], a[end]); } } if (a[begin]>a[right]) { swap(a[begin], a[right]); return begin; } else { return right; } } void QuickSort(int* a, int left, int right) //快排 { assert(a); if (left >= right) return; int div = PartSort(a, left, right); QuickSort(a, left, div - 1); QuickSort(a, div+1, right); }
堆排序
//堆排序 void AdjustDown(int* a, size_t size, size_t parent) { size_t child = parent * 2 + 1; while (child < size) { if (child + 1 < size&&a[child]< a[child + 1]) { ++child; } if (a[child] > a[parent]) { swap(a[child], a[parent]); parent= child; child = parent * 2 + 1; } else { break; } } } void HeapSort(int*a ,size_t size) { assert(a); for (int i = (size - 2) / 2; i >= 0; --i) //建堆 { AdjustDown(a, size, i); } for (size_t i = 0; i < size; ++i) { swap(a[0], a[size - i - 1]); AdjustDown(a, size - i - 1, 0); } }
排序效果:
選擇排序:
設計思想:
//選擇排序(Selection sort)是一種簡單直觀的排序算法。
//它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小元素,然後放到排序序列末尾。
//以此類推,直到所有元素均排序完畢。
void SelectSort(int* a, size_t size) //選擇排序 { assert(a); for (size_t i = 0; i < size-1; i++) { int min = i; //查找最小值 for (size_t j = i+1; j < size; j++) { if (a[min]>a[j]) { min = j; } } //交換 if (min!=i) { swap(a[min], a[i]); } } }
排序效果:
//冒泡排序
//排序思想:
//1、比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
//2、對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。
//3、針對所有的元素重複以上的步驟,除了最後一個。
//4、每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
//void BubbleSort(int* a,size_t size) //{ // for (size_t i = 0; i < size-1; ++i) // { // for (size_t j = i + 1; j < size; ++j) // { // if (a[i]>a[j]) // { // swap(a[i], a[j]); // } // } // } //} //改進 void bubbleSort1(int* a, int size) { int j = 0; while (size > 0) { for (j = 0; j < size - 1; j++) { if (a[j] > a[j + 1]) { swap(a[j], a[j + 1]); } } size--; } }
插入排序:
設計思想:
1.從第一個元素開始,該元素可以認爲已經被排序
2.取出下一個元素,在已經排序的元素序列中從後向前掃描
3.如果該元素(已排序)大於新元素,將該元素移到下一位置
4.重複步驟3,直到找到已排序的元素小於或者等於新元素的位置
5.將新元素插入到該位置中
6.重複步驟2
void InsertSort(int *a, int size) //插入排序 { assert(a); for (int i = 1; i < size; i++) { int cur = i; int next = a[i]; while (i >=0 && a[cur-1] > next) { a[cur] = a[cur-1]; --cur; } a[cur] = next; } }
希爾排序,也稱遞減增量排序算法,是插入排序的一種高速而穩定的改進版本。
該方法的基本思想是:
先將整個待排元素序列分割成若干個子序列(由相隔某個“增量”的元素組成的)分別進行直接插入排序,然後依次縮減增量再進行排序,待整個序列中的元素基本有序(增量足夠小)時,再對全體元素進行一次直接插入排序。
因爲直接插入排序在元素基本有序的情況下(接近最好情況),效率是很高的.
希爾排序是基於插入排序的以下兩點性質而提出改進方法的:
1、插入排序在對幾乎已經排好序的數據操作時,效率高, 即可以達到線性排序的效率
2、但插入排序一般來說是低效的, 因爲插入排序每次只能將數據移動一位>
void ShellSort(int* a,size_t size) { int gap = size; while (gap > 1) { gap = gap / 3 + 1; for (size_t i = 0; i < size - gap; i++) { int end=i; int tmp = a[end + gap]; while (end >= 0 && a[end] > tmp) { swap(a[end + gap], a[end]); end -= gap; } a[end + gap] = tmp; } } }
排序效果: