Linux c 八種排序
阿新 • • 發佈:2018-12-24
#include<stdio.h> #include<stdlib.h> //氣泡排序 void bubleSort(int data[], int n); //快速排序 void quickSort(int data[], int low, int high); int findPos(int data[], int low, int high); //插入排序 void bInsertSort(int data[], int n); //希爾排序 void shellSort(int data[], int n); //選擇排序 void selectSort(int data[], int n); //堆排序 void heapSort(int data[], int n); void swap(int data[], int i, int j); void heapAdjust(int data[], int i, int n); //歸併排序 void mergeSort(int data[], int first, int last); void merge(int data[], int low, int mid, int high); //基數排序 void radixSort(int data[], int n); int getNumPos(int num, int pos); int main() { int data[10] = {43, 65, 4, 23, 6, 98, 2, 65, 7, 79}; int i; printf("原先陣列:"); for(i=0;i<10;i++) { printf("%d ", data[i]); } printf("\n"); /*printf("氣泡排序:"); bubleSort(data, 10); for(i=0;i<10;i++) { printf("%d ", data[i]); } printf("\n"); printf("快速排序:"); quickSort(data, 0, 9); for(i=0;i<10;i++) { printf("%d ", data[i]); } printf("\n"); printf("插入排序:"); bInsertSort(data,10); for(i=0;i<10;i++) { printf("%d ", data[i]); } printf("\n"); printf("希爾排序:"); shellSort(data, 10); for(i=0;i<10;i++) { printf("%d ", data[i]); } printf("\n"); printf("選擇排序:"); selectSort(data, 10); for(i=0;i<10;i++) { printf("%d ", data[i]); } printf("\n"); int data[11] = {-1, 43, 65, 4, 23, 6, 98, 2, 65, 7, 79}; int i; printf("原先陣列:"); int data[11] = {-1, 43, 65, 4, 23, 6, 98, 2, 65, 7, 79}; for(i=1;i<11;i++) { printf("%d ", data[i]); } printf("\n"); printf(" 堆排序:"); heapSort(data, 10); for(i=1;i<11;i++) { printf("%d ", data[i]); } printf("\n"); printf("歸併排序:"); mergeSort(data, 0, 9); for(i=0;i<10;i++) { printf("%d ", data[i]); } printf("\n");*/ printf("基數排序:"); radixSort(data, 10); for(i=0;i<10;i++) { printf("%d ", data[i]); } printf("\n"); return 0; } /*--------------------氣泡排序---------------------*/ void bubleSort(int data[], int n) { int i,j,temp; //兩個for迴圈,每次取出一個元素跟陣列的其他元素比較 //將最大的元素排到最後。 for(j=0;j<n-1;j++) { //外迴圈一次,就排好一個數,並放在後面, //所以比較前面n-j-1個元素即可 for(i=0;i<n-j-1;i++) { if(data[i]>data[i+1]) { temp = data[i]; data[i] = data[i+1]; data[i+1] = temp; } } } } /*--------------------快速排序---------------------*/ int findPos(int data[], int low, int high) { //將大於t的元素趕到t的左邊,大於t的元素趕到t的右邊 int t = data[low]; while(low < high) { while(low < high && data[high] >= t) { high--; } data[low] = data[high]; while(low < high && data[low] <=t) { low++; } data[high] = data[low]; } data[low] = t; //返回此時t在陣列中的位置 return low; } //在陣列中找一個元素,對大於該元素和小於該元素的兩個陣列進行再排序 //再對兩個陣列分為4個數組,再排序,直到最後每組只剩下一個元素為止 void quickSort(int data[], int low, int high) { if(low > high) { return; } int pos = findPos(data, low, high); quickSort(data, low, pos-1); quickSort(data, pos+1, high); } /*--------------------插入排序---------------------*/ void bInsertSort(int data[], int n) { int low,high,mid; int temp,i,j; for(i=1;i<n;i++) { low = 0; //把data[i]元素插入到它的前面data[0-(i-1)]中 temp =data[i]; high = i-1; //該while是折半,縮小data[i]的範圍(優化手段) while(low <= high) { mid = (low+high)/2; if(data[mid] > temp) { high = mid-1; } else { low = mid+1; } } int j = i; //讓data與已經排序好的陣列的各個元素比較,小的放前面 while((j > low) && data[j-1] > temp) { data[j] = data[j-1]; --j; } data[low] = temp; } } /*--------------------希爾排序---------------------*/ void shellSort(int * data, int n) { int step,i,j,key; //將陣列按照step分組,不斷二分到每組只剩下一個元素 for(step=n/2;step>0;step/=2) { //將每組中的元素排序,小的在前 for(i=step;i<n;i++) { key = data[i]; for(j=i-step;j>=0 && key<data[j];j-=step) { data[j+step] = data[j]; } //和上面的for迴圈一起,將組中小的元素換到陣列的前面 data[j+step] = key; } } } /*--------------------選擇排序---------------------*/ void selectSort(int data[], int n) { int i,j,mix,temp; //每次迴圈陣列,找出最小的元素,放在前面,前面的即為排序好的 for(i=0;i<n-1;i++) { //假設最小元素的下標 int mix = i; //將上面假設的最小元素與陣列比較,交換出最小的元素的下標 for(j=i+1;j<n;j++) { if(data[j] < data[mix]) { mix = j; } } //若陣列中真的有比假設的元素還小,就交換 if(i != mix) { temp = data[i]; data[i] = data[mix]; data[mix] = temp; } } } /*--------------------堆排序---------------------*/ //堆排序將陣列先組成二叉樹,預設從陣列的data[1]開始排,data[0]是 //無效資料 void heapSort(int data[], int n) { int i; //先將陣列組成一棵完全二叉樹 //從2/n開始,就是從倒數第二排結點往前開始 for(i=n/2;i>0;i--) { heapAdjust(data, i, n); } //迴圈每個結點,將大的結點交換到堆頂 for(i=n;i>1;i--) { swap(data, 1, i); //每次交換完都要調整二叉樹,將剩下的最大的結點交換到堆頂 heapAdjust(data, 1, i-1); } } //交換函式 void swap(int data[], int i, int j) { int temp; temp = data[i]; data[i] = data[j]; data[j] = temp; } void heapAdjust(int data[], int i, int n) { int j, temp; //假設第一個結點的元素是最大的 temp = data[i]; //i結點:2*i是i結點的左結點,2*i+1是i結點的右結點 //把結點元素大的交換到前面 for(j=2*i;j<=n;j*=2) { if(j < n && data[j] < data[j+1]) { j++; } if(temp >= data[j]) { break; } data[i] = data[j]; i = j; } data[i] = temp; } /*--------------------歸併排序---------------------*/ void mergeSort(int data[], int first, int last) { int mid = 0; //將陣列不停的二分分組再組合,直到每組只剩一個元素 if(first < last) { mid = (first+last)/2; mergeSort(data, first, mid); mergeSort(data, mid+1, last); merge(data, first, mid, last); } return; } void merge(int data[], int low, int mid, int high) { int i, k; //定義一個臨時陣列存放傳進來的無序陣列排好序之後的陣列 int *temp = (int *)malloc((high-low+1)*sizeof(int)); //將無序陣列分成兩個序列 int left_low = low; int left_high = mid; int right_low = mid+1; int right_high = high; //將兩個序列比較排序,小的排前 for(k=0;left_low<=left_high && right_low<=right_high;k++) { if(data[left_low]<=data[right_low]) { temp[k] = data[left_low++]; } else{ temp[k] = data[right_low++]; } } //左序列如果有剩下元素未排序,加到臨時陣列的末尾 if(left_low <= left_high) { for(i=left_low;i<=left_high;i++) { temp[k++] = data[i]; } } //右序列如果有剩下元素未排序,加到臨時陣列的末尾 if(right_low <= right_high) { for(i=right_low;i<=right_high;i++) { temp[k++] = data[i]; } } //將排好序的小分組轉移到原陣列中 for(i=0;i<high-low+1;i++) { data[low+i] = temp[i]; } free(temp); return; } /*--------------------基數排序---------------------*/ //該函式的作用是找出num的pos位數的數字(比如:23的個位數數字是3) int getNumPos(int num, int pos) { int i; int temp = 1; for(i=0;i<pos-1;i++) { temp *= 10; } return (num / temp) % 10; } void radixSort(int data[], int n) { int i,j,k,pos,num,index; //這幾句話是建立一個從0-9(行)× (n+1)(列)的網格,第一列從上往下是0-9, //第二列是該行包含的元素個數,預設為0個 int *radixArrays[10]; for(i=0;i<10;i++) { radixArrays[i] = (int *)malloc(sizeof(int) * (n+1)); radixArrays[i][0] = 0; } //pos最大為31為數,計算機能承受的最大範圍了 for(pos=1;pos<=31;pos++) { //該for迴圈是將陣列的元素按照位數(pos)的值放進網格內 for(i=0;i<n;i++) { num = getNumPos(data[i], pos); index = ++radixArrays[num][0]; radixArrays[num][index] = data[i]; } //該for迴圈是將上面的for迴圈已經按照某個位數(pos)排列好的元素存入陣列 for(i=0,j=0;i<10;i++) { for(k=1;k<=radixArrays[i][0];k++) { data[j++] = radixArrays[i][k]; } //清空網格,以便給下個位數排列 radixArrays[i][0] = 0; } } }
以上排序演算法的優劣(時間複雜度和空間複雜度對比):