1. 程式人生 > >常見的4種排序演算法

常見的4種排序演算法

1、氣泡排序

最簡單的一種排序演算法。先從陣列中找到最大值(或最小值)並放到陣列最左端(或最右端),然後在剩下的數字中找到次大值(或次小值),以此類推,直到陣列有序排列。演算法的時間複雜度為O(n^2)。

// 氣泡排序
void BubbleSort(int arr[], int length)
{
	for (int i = 0; i < length; i++)
	{
		for (int j = 0; j < length -  i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int temp;
				temp = arr[j + 1];
				arr[j + 1] = arr[j];
				arr[j] = temp;
			}
		}
	}
}

2、選擇排序

 每一趟在n-i+1(i=1,2,...,n-1)個記錄中選取關鍵字最小的記錄作為有序序列中第i個記錄。具體來說,假設長度為n的陣列arr,要按照從小到大排序,那麼先從n個數字中找到最小值min1,如果最小值min1的位置不在陣列的最左端(也就是min1不等於arr[0]),則將最小值min1和arr[0]交換,接著在剩下的n-1個數字中找到最小值min2,如果最小值min2不等於arr[1],則交換這兩個數字,依次類推,直到陣列arr有序排列。演算法的時間複雜度為O(n^2)。

// 選擇排序
void SelectionSort(int arr[], int length)
{
	for (int i = 0; i < length; i++)
	{
		int index = i;
		for (int j = i+1; j < length; j++)
		{
			if (arr[j] < arr[index])
			{
				index = j;
			}
		}
		if (index == i)
			continue;
		else
		{
			int temp;
			temp = arr[index];
			arr[index] = arr[i];
			arr[i] = temp;
		}
	}
}

 

3、快速排序

快速排序的基本思想是:通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,已達到整個序列有序。一趟快速排序的具體過程可描述為:從待排序列中任意選取一個記錄(通常選取第一個記錄)作為基準值,然後將記錄中關鍵字比它小的記錄都安置在它的位置之前,將記錄中關鍵字比它大的記錄都安置在它的位置之後。這樣,以該基準值為分界線,將待排序列分成的兩個子序列。

一趟快速排序的具體做法為:設定兩個指標low和high分別指向待排序列的開始和結尾,記錄下基準值baseval(待排序列的第一個記錄),然後先從high所指的位置向前搜尋直到找到一個小於baseval的記錄並互相交換,接著從low所指向的位置向後搜尋直到找到一個大於baseval的記錄並互相交換,重複這兩個步驟直到low=high為止。

// 快速排序
void QuickSort(int arr[], int start, int end)
{
	if (start >= end)
		return;
	int i = start;
	int j = end;
	// 基準數
	int baseval = arr[start];
	while (i < j)
	{
		// 從右向左找比基準數小的數
		while (i < j && arr[j] >= baseval)
		{
			j--;
		}
		if (i < j)
		{
			arr[i] = arr[j];
			i++;
		}
		// 從左向右找比基準數大的數
		while (i < j && arr[i] < baseval)
		{
			i++;
		}
		if (i < j)
		{
			arr[j] = arr[i];
			j--;
		}
	}
	// 把基準數放到i的位置
	arr[i] = baseval;
	// 遞迴
	QuickSort(arr, start, i - 1);
	QuickSort(arr, i + 1, end);
}

 

快速排序具有最好的平均效能(average behavior),但最壞效能(worst case behavior)和插入排序

相同,也是O(n^2)。比如一個序列5,4,3,2,1,要排為1,2,3,4,5。按照快速排序方法,每次只會有一個數據進入正確順序,不能把資料分成大小相當的兩份,很明顯,排序的過程就成了一個歪脖子樹,樹的深度為n,那時間複雜度就成了O(n^2)。儘管如此,需要排序的情況幾乎都是亂序的,自然效能就保證了。據書上的測試圖來看,在資料量小於20的時候,插入排序具有最好的效能。當大於20時,快速排序具有最好的效能,歸併(merge sort)和堆排序(heap sort)也望塵莫及,儘管複雜度都為nlog2(n)。

4、插入排序

插入排序的基本思想就是將無序序列插入到有序序列中。

// 插入排序
void InsertSort(int arr[], int length)
{
	for (int i = 1; i < length; i++)
	{
		int j;
		if (arr[i] < arr[i - 1])
		{
			int temp = arr[i];
			for (j = i - 1; j >= 0 && temp < arr[j]; j--)
			{
				arr[j + 1] = arr[j];
			}
			arr[j + 1] = temp;
		}
	}
}