1. 程式人生 > >資料結構:交換排序(氣泡排序、快速排序)

資料結構:交換排序(氣泡排序、快速排序)

1.氣泡排序,它重複地走訪過要排序的元素列,依次比較兩個相鄰的元素,如果他們的順序(如從大到小、首字母從A到Z)錯誤就把他們交換過來。走訪元素的工作是重複地進行直到沒有相鄰元素需要交換,也就是說該元素已經排序完成。

氣泡排序演算法的原理如下:

  1. 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。

  2. 對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。

  3. 針對所有的元素重複以上的步驟,除了最後一個。

  4. 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。

2.快速排序(Quicksort)是對氣泡排序的一種改進。快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞進行,以此達到整個資料變成有序序列。

一趟快速排序的演算法是:

1)設定兩個變數i、j,排序開始的時候:i=0,j=N-1;

2)以第一個陣列元素作為關鍵資料,賦值給key,即key=A[0];

3)從j開始向前搜尋,即由後開始向前搜尋(j--),找到第一個小於key的值A[j],將A[j]和A[i]互換;

4)從i開始向後搜尋,即由前開始向後搜尋(i++),找到第一個大於key的A[i],將A[i]和A[j]互換;

5)重複第3、4步,直到i=j; (3,4步中,沒找到符合條件的值,即3中A[j]不小於key,4中A[i]不大於key的時候改變j、i的值,使得j=j-1,i=i+1,直至找到為止。找到符合條件的值,進行交換的時候i, j指標位置不變。另外,i==j這一過程一定正好是i+或j-完成的時候,此時令迴圈結束)。

附:各種排序時空複雜度對比

氣泡排序實現:

#include<stdio.h>
#include<stdlib.h>


void BubbleSort(int arr[], int len)
{
	bool flag = false;
	int count = 0;
	for (int i = 0; i < len - 1; i++)
	{
		flag = false;
		for (int j = 0; j < len - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				flag = true;
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
		if (!flag)
		{ 
			return;
		}
	}
}

 快速排序實現:

#include<stdio.h>
#include<stdlib.h>
#include<stack>
#include<time.h>

void insertSort(int arr[], int startindex, int endindex)
{
	int tmp = 0;
	int i = startindex + 1;
	int j = i - 1;
	for (i; i <= endindex; ++i)
	{
		tmp = arr[i];
		for (j = i - 1; j >= startindex && arr[j] > tmp; --j)
		{
			arr[j + 1] = arr[j];
		}
		arr[j + 1] = tmp;
	}
}
int partition(int arr[], int left, int right)
{
	int key = arr[left];
	while (left < right)
	{
		while (left < right && arr[right] >= key)right--;
		arr[left] = arr[right];
		while (left < right && arr[left] <= key)left++;
		arr[right] = arr[left];
	}
	arr[left] = key;
	return left;
}
void Quick(int arr[], int startindex, int endindex)
{
	if (startindex < endindex)
	{			
		if (endindex - startindex + 1 <= 20)
		{
			insertSort(arr, startindex, endindex);
			return;
		}
		int left = -1;
		int right = -1;
		int k = partition(arr, startindex, endindex);
		Quick(arr, startindex, k - 1);
		Quick(arr, k + 1, endindex);
	}
}

void QuickSort(int arr[], int len)
{
	Quick(arr, 0, len - 1);
}