(資料結構排序的實驗四)快速,冒泡,簡單選擇,直接插入排序的c語言實現!!
阿新 • • 發佈:2019-01-05
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">#include<stdio.h> /****四種(冒泡,選擇,快速,插入)排序(遞增)下標都是從0開始的******/ int dig[1000]; int n; /*****1 (交換類) 氣泡排序***時間複雜度:O(n^2)***/ /**思想:一趟排序中(從起始位置開始)是將最大的關鍵字沉到陣列的底部。 n個數字排序,需要n-1趟,(假設就兩個數字,那麼只要一趟排序將最大的數值沉到陣列底部,此序列就是有序的啦) 若序列本身就是有序的,那麼只要一趟即可,(為什麼還需要一趟呢?此趟是驗證序列都沒有發生交換,那麼此序列就是有序的) **/</span> void bubblingSort(int msort[],int num){ int tmp; int flag; for(int i = 0;i < num-1;i++){ flag = 0; for(int j = 0;j < num-i-1;j++){ if(msort[j]>msort[j+1]){ flag = 1; tmp = msort[j]; msort[j] = msort[j+1]; msort[j+1] = tmp; } } if(!flag) break; } for(int i = 0;i < num;i++){ printf("%d ",msort[i]); } printf("\n"); } /****2 (插入類) 直接插入排序***O(n^2)**/ /** 思想:假設 2,5,7,10 已經排好了, 而接下來 數字式 6 ,一看就知道把 6 插入到5 和 7 之間。 怎麼插入呢?:邊插邊將陣列後移。6 比10 小, 那麼10 後移;6比7小,7後移;6比5大,那麼就把6插到5的後邊(5的後邊是個空的,因為前面已經把陣列後移啦!!) **/ void insertSort(int msort[],int num){ int tmp,j; for(int i = 1;i < num;i++){ tmp = msort[i]; for( j = i-1;j >= 0;j--){ if(tmp<msort[j]){ msort[j+1] = msort[j]; } else{ break; } } msort[j+1] = tmp; } for(int i = 0;i <num;i++){ printf("%d ",msort[i]); } printf("\n"); } /****3 (選擇類) 簡單選擇排序****O(n^2)*/ /** 思想:第i 趟排序是指從n-i-1個記錄中,找出一個最小的記錄與第i個記錄交換。那麼第i個記錄就是較小的。 列如:第一趟排序:從n個記錄中(從dig[1]...dig[n])找到最小的與第一個記錄交換,那麼第一個就是最小的。 第二趟排序:從陣列後面的n-1個記錄中(從dig[2].....dig[n]),找出一個次小的,與第2個記錄交換。 由此看來也是需要n-1趟排序 **/ void selectSort(int msort[],int num){ int minn,pos; for(int i = 0;i < num-1;i++){ minn = 1111111; for(int j = i;j < num;j++){ if(msort[j]<minn){ minn = msort[j]; pos = j; } } if(i!=pos){ int tmp; tmp = msort[pos]; msort[pos] = msort[i]; msort[i] = tmp; } } for(int i = 0;i <num;i++){ printf("%d ",msort[i]); } printf("\n"); } /****4 (交換類) 快速排序***O(nlogn)**/ /** 思想:待排的序列:dig[start].....dig[end],首先任意選取一個記錄(通常以第一個記錄作為樞軸(啥是樞軸?其實樞軸也沒啥概念(不用理解他))) 然後按照下述原則重新排列其餘記錄。將所有關鍵字(就是數組裡的值)小於它的記錄放在它的位置之前,將所有關鍵字大於它的記錄放在它的位置之後。 由此以該“樞軸”記錄最後所落的位置i作為分界線,將序列dig[start]....dig[end],分割成兩個兩個子序列dig[start]...dig[i-1](此序列的值都是無序的但是他們的值都小於樞軸的值) 和dig[i+1]....dig[end]((此序列的值也是無序的但是他們的值都大於樞軸的值)。這個過程為一次劃分。!!! 劃分過程的具體實現:附設兩個指標(此處的指標並不是指向記憶體地址的指標,而是指向陣列的位置)low,high。low的初值=start,high = end; 設樞軸記錄的關鍵字為pivotkey,則首先從high所指向位置向前搜尋找到第一個關鍵字小於pivotkey的記錄和樞軸的記錄交換,然後從low所指向的位置向後搜尋找到第一個關鍵字大於pivotkey的記錄和樞軸的記錄交換。 重複這兩步,直至low==high為止。(為什麼要附設兩個指標從兩邊開始呢?樞軸右邊的都是大於它的,那麼只要從右邊找到第一個小於樞軸的 和樞軸交換一下,那麼小於樞軸的記錄就到了樞軸的左邊。樞軸的左邊也是同樣道理) 快排的實現用到遞迴。 **/ // 劃分 劃分操作的時間複雜度是O(n) int mpartition(int msort[],int low,int high){ int pivotkey = msort[low]; int tmp; while(low < high){ while(low < high&&msort[high]>=pivotkey) --high; tmp = msort[low]; msort[low] = msort[high]; msort[high] = tmp; while(low < high&&msort[low]<=pivotkey) ++low; tmp = msort[low]; msort[low] = msort[high]; msort[high] = tmp; } return low; } /*****上述劃分每一次交換需要進行3次記錄移動(賦值)的操作。而實際上,對樞軸記錄的賦值操作是多餘的,因為只有到了low==high時 此位置才是樞軸記錄的最後位置,因此只要在此位置給樞軸賦值即可。******/ int improve_mpartition(int msort[],int low,int high){ int pivotkey = msort[low]; int tmp; while(low < high){ while(low < high&&msort[high]>=pivotkey) --high; msort[low] = msort[high]; while(low < high&&msort[low]<=pivotkey) ++low; msort[high] = msort[low]; } msort[low] = pivotkey; return low; } // 遞迴操作的時間複雜度是o(log n) void quickSort(int msort[],int low,int high){ int pivotloc; /***遞迴的終止條件是待排序的子序列是一個序列(也就是(序列的左邊界)low<high(序列的右邊界))***/ if(low < high){ pivotloc = improve_mpartition(msort,low,high); quickSort(msort,low,pivotloc-1); quickSort(msort,pivotloc+1,high); } } int main(){ /** 輸入n個數 **/ scanf("%d",&n); for(int i = 0; i < n;i++){ scanf("%d",&dig[i]); } /**** 因為陣列作為引數無法實現值傳遞, 所以用迴圈將陣列實現複製 ****/ int m1sort[100],m2sort[100],m3sort[100],m4sort[100]; for(int i = 0;i < n;i++){ m1sort[i] = dig[i];m2sort[i] = dig[i]; m3sort[i] = dig[i];m4sort[i] = dig[i]; // m5sort[i] = dig[i]; } /****1 (交換類) 氣泡排序*****/ printf("氣泡排序\n"); bubblingSort(m1sort,n); /****2 (插入類) 直接插入排序*****/ printf("直接插入排序\n"); insertSort(m2sort,n); /****3 (選擇類) 簡單選擇排序*****/ printf("簡單選擇排序\n"); selectSort(m3sort,n); /****4 (交換類) 快速排序*****/ printf("快速排序\n"); quickSort(m4sort,0,n-1); for(int i = 0;i < n;i++){ printf("%d ",m4sort[i]); } }</span></span></span>