交換排序——氣泡排序和快速排序
阿新 • • 發佈:2019-02-07
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;
}
}