voidSelectSort(int*a,int size){assert(a);int left =0;int right = size -1;while(left < right){int min = left;int max = left;for(int i = left; i <= right; i++){if(a[i]< a[min])//選出最小{
min = i;}if(a[i]> a[max])//選出最大{
max = i;}}Swap(&a[left],&a[min]);if(max == left)//若max和left相等,則經過上一步交換,導致原max處爲最小值,而min處爲最大值{
max = min;//更新max,讓其位置爲最大值}Swap(&a[right],&a[max]);
left++;
right--;}}
voidBubbleSort(int*a,int size){assert(a);for(int i =0; i < size -1; i++){int flag =0;for(int j =0; j < size - i -1; j++)//一趟排序{if(a[j]>a[j +1]){
flag =1;Swap(&a[j],&a[j +1]);}}if(flag ==0)//如果一趟排序後發現沒有一次交換,則說明已經有序{break;}}}
voidQuickSortR(int*a,int left,int right){assert(a);if(left >= right){return;}if(right - left <10)//優化:在區間較小時,插入排序的效率高{InsertSort(a, right - left +1);}else{int div =PartSort1(a, left, right);QuickSortR(a, left, div -1);QuickSortR(a, div +1, right);}}
voidQuickSort(int*a,int left,int right){assert(a);
Stack s;StackInit(&s);StackPush(&s, left);StackPush(&s, right);while(!StackEmpty(&s)){int end =StackTop(&s);StackPop(&s);int begin =StackTop(&s);StackPop(&s);int div =PartSort1(a, begin, end);if(begin < div -1){StackPush(&s, begin);StackPush(&s, div -1);}if(div +1< end){StackPush(&s, div +1);StackPush(&s, end);}}}
分析:
時間複雜度:
最好情況:O(N*lgN)
最壞情況:O(N^2)
平均情況:O(N*lgN)
空間複雜度:O(lgN)——遞歸深度
穩定性:不穩定
七、歸併排序
基本思想:
將待排序的元素序列分成兩個長度相等的子序列,對每一個子序列排序,然後再將它們合併成一個有序序列。
圖解:
合併圖解:
代碼實現:
//歸併局部遞歸void_MergeSort(int*a,int left,int right,int*tmp){if(left >= right){return;}if(right - left <10)//優化:在區間較小時,插入排序的效率高{InsertSort(a, right - left +1);return;}int mid = left +((right - left)>>1);_MergeSort(a, left, mid, tmp);_MergeSort(a, mid +1, right, tmp);int p = left;int q = mid +1;int index =0;while(p <= mid&&q <= right){if(a[p]<= a[q])//加上"="可保持穩定性{
tmp[index++]= a[p++];}else{
tmp[index++]= a[q++];}}while(p <= mid){
tmp[index++]= a[p++];}while(q <= right){
tmp[index++]= a[q++];}int j =0;for(int i = left; i <= right; i++){
a[i]= tmp[j++];}}voidMergeSort(int*a,int left,int right){assert(a);int*tmp =(int*)malloc((right - left +1)*sizeof(int));memset(tmp,0,(right - left +1)*sizeof(int));//或者:int *tmp = (int *)calloc(right - left + 1,sizeof(int));_MergeSort(a, left, right, tmp);free(tmp);}
分析:
時間複雜度:O(N*lgN)
空間複雜度:O(N)——臨時數組
穩定性:穩定
八、計數排序
基本思想:
統計待排序序列中每個元素出現的次數,再根據統計的結果重新對元素進行回收。
圖解:
代碼實現:
voidCountSort(int*a,int size){assert(a);//(1)找出最值,確定範圍,以便開闢空間int max = a[0];int min = a[0];int index =0;for(index =1; index < size; index++){if(a[index]>max){
max = a[index];}if(a[index]< min){
min = a[index];}}int range= max - min +1;//(2)統計出現次數int*tmp =(int*)calloc(range,sizeof(int));for(index =0; index < size; index++){
tmp[a[index]- min]++;}//(3)回收int i =0;for(index =0; index < range; index++){while(tmp[index]){
a[i++]= index + min;
tmp[index]--;}}free(tmp);
tmp =NULL;}