1. 程式人生 > >交換排序——氣泡排序和快速排序

交換排序——氣泡排序和快速排序

1. 氣泡排序

(1)演算法思想:將序列中的第一個元素和第二個元素相比較,如前者大於後者,則交換,否則不交換;再將第二個元素和第三個元素比較,若前者大於後者,則交換兩個元素的位置,否則不交換,依次進行,直到最後一個元素,經過如此一輪,則n個元素中最大的一個被放在了最後。此後,再進行相同的過程。

(2)基本實現:

void BubbleSort(DataType* arr, int sz)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < sz - 1; i++)
	{
		bool change = false;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j]>arr[j + 1])
			{
				swap(arr[j], arr[j + 1]);
				change = true;
			}
		}
	}
}

(3)演算法效能:

                      時間複雜度:O(n^2);

                      空間複雜度:O (1);

                       穩定性:穩定

2. 快速排序

(1)演算法思想:快速排序的平均時間效能最快。任選序列中的一個數據元素(通常選取第一個資料元素或者最後一個數據元素)作為樞軸,用它和所有剩餘資料元素進行比較,將所有較它小的元素排在它前面,將所有比它大的元素排在它後面,經過一趟排序後,可按此元素所在位置為界,將序列劃分為兩個部分,再重複此過程。

(2)基本實現:

       hare演算法:

size_t Pation1(DataType *arr, int left, int right)
{
	int begin = left;
	int end = right - 1;
	int key = arr[end];
	while (begin<end)
	{
		while (begin < end&&arr[begin] <= key)
		{
			begin++;
		}
		swap(arr[begin], arr[end]);
		while (begin<end&&arr[end]>=key)
		{
			end--;
		}
		swap(arr[end], arr[begin]);
    }
	return begin;
}

      挖坑演算法:

size_t Pation2(DataType* arr, int left, int right)
{
	int begin = left;
	int end = right-1 ;
	int key = arr[end];
	while (begin < end)
	{
		while (begin < end&&arr[begin] <= key)
			begin++;
		if (begin < end)
			arr[end] = arr[begin];
		while (begin < end&& arr[end] >= key)
			end--;
		if (begin < end)
			arr[begin] = arr[end];

       arr[begin] = key;
	 }
	return begin;
}

   兩指標演算法:     

size_t Pation3(DataType* arr, int left, int right)
{
	int sz = right - left;
	int cur = 0;
	int pre = cur - 1;
        int index=right-1;
	int key = arr[index];
	if (index != right - 1)
	{
		swap(arr[index], arr[right - 1]);
	}
	while (cur < sz)
	{
		if (arr[cur] <= key&&++pre != cur)
		{
			swap(arr[pre], arr[right - 1]);
		}
		cur++;
	}
	if (++pre != right)
	{
		swap(arr[++pre], arr[sz - 1]);
	}
	return pre;
}

(3)演算法效能:

                      時間複雜度:O(n logn);

                      空間複雜度:O (logn);

                       穩定性:不穩定

在上面取樞軸的過程中,以最後一個元素為基準,這樣在一般情況情況下是適用的,但是對於有序的序列來說,效率就比較低了,此時我們可以利用三數取中法來選取樞軸。

int GetMidData(DataType* arr, int left, int right)
{
	int mid = left + ((right - left) >> 1);
	if (arr[left]<arr[right - 1])
	{
		if (arr[left] > arr[mid])
			return left;
		else if (arr[right - 1] < arr[mid])
			return right - 1;
		else
			return mid;
	}
	else
	{
		if (arr[left] < arr[mid])
			return left;
		else if (arr[right - 1]>arr[mid])
			return right - 1;
		else
			return mid;
	}

}