1. 程式人生 > >資料結構排序演算法之快速排序(c語言實現)

資料結構排序演算法之快速排序(c語言實現)

快排的原理就是通過一趟排序將待排記錄分割成獨立的兩部分,其中的一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。這其中,可以使用遞迴呼叫某一關鍵函式的辦法來實現這樣的功能。

分割的方法就是,選取一個樞軸,將所有關鍵字比它小的記錄都安置在它的位置之前,將所有關鍵字較它大的記錄都安置在它的位置之後。

具體做法就是:取序列的兩端,一端下標或者指標為low,另一端的下標或指標為high。將high所指的元素的值與樞軸作比較,若比樞軸的值大就使high前移,直至移到某一位置,其值比樞軸的值小,則將其賦給low的位置(將比樞軸記錄小的移到低端)然後從low所指的位置起向後搜尋,搜尋過程與high端同理,不過是若比樞軸小就繼續使low後移,直至移到某一位置,其值比樞軸的值大,則將它賦給high的位置(將比樞軸記錄大的移到高階)

。如此反覆,直到low=high則停止。返回的pivotloc值為最後low的值。

先上程式碼

#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;
}

執行是成功的。