資料結構排序演算法之快速排序(c語言實現)
阿新 • • 發佈:2019-02-09
快排的原理就是通過一趟排序將待排記錄分割成獨立的兩部分,其中的一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。這其中,可以使用遞迴呼叫某一關鍵函式的辦法來實現這樣的功能。
分割的方法就是,選取一個樞軸,將所有關鍵字比它小的記錄都安置在它的位置之前,將所有關鍵字較它大的記錄都安置在它的位置之後。
具體做法就是:取序列的兩端,一端下標或者指標為low,另一端的下標或指標為high。將high所指的元素的值與樞軸作比較,若比樞軸的值大就使high前移,直至移到某一位置,其值比樞軸的值小,則將其賦給low的位置(將比樞軸記錄小的移到低端);然後從low所指的位置起向後搜尋,搜尋過程與high端同理,不過是若比樞軸小就繼續使low後移,直至移到某一位置,其值比樞軸的值大,則將它賦給high的位置(將比樞軸記錄大的移到高階)
先上程式碼
#include "stdafx.h" #include "stdio.h" #include "malloc.h" #include <string.h> #include <cstdlib> #define OK 1 #define ERROR 0 typedef int Status; typedef struct { int *Data; int length; }SqList; Status InitSqList(SqList *S) { int n; printf("請輸入需排序的資料個數:\n"); scanf_s("%d", &n); getchar();//吸收換行符 S->length = n; S->Data = (int*)malloc((n + 1)*sizeof(int)); if (!S->Data)return ERROR; S->Data[0] = 0;//這裡用於儲存pivotkey的值 for (int i = 1; i <= n; i++) { printf("第%d個數為:", i); scanf_s("%d", &S->Data[i]); getchar();//吸收換行符 } return OK; } int Partition(SqList *S, int low, int high) { int pivotkey = S->Data[low]; S->Data[0] = S->Data[low];//用S->Data[0]來儲存最開始的S->Data[low]的值,即pivotkey,因為後面會被覆蓋掉,這樣就避免了很多次的賦值交換 while (low < high) { while (low < high&&S->Data[high] >= pivotkey) high--;//使high指向一個比pivotkey值小的數的下標 S->Data[low] = S->Data[high];//將這個比pivotkey還要小的數放到前半部分 while (low < high&&S->Data[low] <= pivotkey) low++;//使low指向一個比pivotkey值大的數的下標 S->Data[high] = S->Data[low];//將這個比pivotkey還要小的數放到後半部分 } S->Data[low] = S->Data[0];//最後將被覆蓋掉的值存入 return low;//此時的low=high=要返回的pivotkey } void QSort(SqList *S, int low, int high) { int pivotloc; if (low < high) { pivotloc = Partition(S, low, high);//獲取一個pivot的下標loc,它的前面的元素都比它小,它的後面的元素都比它大 QSort(S, low, pivotloc - 1); QSort(S, pivotloc + 1, high); } } void QuickSort(SqList *S) { QSort(S, 1, S->length); } int main() { SqList S; InitSqList(&S); QuickSort(&S); printf("\n"); for (int i = 1; i <= S.length; i++) { printf("第%d個數為\t%d\n", i, S.Data[i]); } system("pause"); return 0; }
執行是成功的。