else {
if (a[mid] < a[right])
{
return mid;
}
else if (a[left] > a[right])
{
return left;
}
else {
return right;
}
}
}
挖坑法
思路分析
1.將選出的基準(zhǔn)值key的位置作為一個(gè)坑(pivot)。
2.然后從最后一位開始遍歷,找到比key小的值停下,將這個(gè)值放到坑里面,然后坑就到了新位置
3.再從第一位開始遍歷,找到比key大的值停下,將這個(gè)值放在新的坑里面,坑又到了新的位置
4.依次反復(fù)進(jìn)行直到前后遍歷碰撞。
圖解如下:
?代碼實(shí)現(xiàn)
int PartSort1(int* a, int left, int right)
{
int Index = GetMidIndex(a,left, right);//這里是三數(shù)取中,會(huì)在下面講解
Swap(&a[left], &a[Index]);
int begin = left;
int end = right;
int pivot = begin;
int key = a[begin];
while (begin < end)
{
while (begin < end && a[end] >= key)
{
end--;
}
a[pivot] = a[end];
pivot = end;
while (begin < end && a[begin] <= key)
{
begin++;
}
a[pivot] = a[begin];
pivot = begin;
}
pivot = begin;
a[pivot] = key;
return pivot;
}
?左右指針法
思路分析
1.左指針begin,右指針end,利用這兩個(gè)指針前后遍歷分別找到比key大的值和比key小的值。
2.將兩個(gè)值進(jìn)行交換,再重復(fù)1的操作。
3.當(dāng)begin=end時(shí)操作停止,最后將key值與begin位置的值進(jìn)行交換,完成了排序。
圖解如下:
?
?代碼實(shí)現(xiàn)
int PartSort2(int* a, int left, int right)
{
int Index = GetMidIndex(a, left, right);
Swap(&a[left], &a[Index]);
int begin = left;
int end = right;
int key = begin;
while (end > begin)
{
while (end > begin && a[end] >= a[key])
{
end--;
}
while (end > begin && a[begin] <= a[key])
{
begin++;
}
Swap(&a[end], &a[begin]);
}
Swap(&a[begin], &a[key]);
return begin;
}
前后指針法
思路分析
1.前指針prev,后指針cur,讓cur去找比key大的值,找到后prev向前移動(dòng)一位(prev++),并且與cur位置的值進(jìn)行交換。
2.重復(fù)執(zhí)行1的操作,知道cur把所有的數(shù)據(jù)遍歷完成。
3.最后將key值與prev位置的值進(jìn)行交換,完成排序。
圖解如下:
?
代碼實(shí)現(xiàn)
int PartSort3(int* a, int left, int right)
{
int prev = left;
int cur = left + 1;
int key = left;
while (cur <= right)
{
if (a[cur] < a[key]&&prev++ != cur)
{
Swap(&a[cur], &a[prev]);
}
cur++;
}
Swap(&a[prev], &a[key]);
return prev;
}
快速排序?qū)崿F(xiàn)
利用分治思想,用遞歸算法來進(jìn)行代碼實(shí)現(xiàn)。
void QuickSort(int* a, int left, int right)
{
if (left >= right)//遞歸條件
{
return;
}
int KeyIndex = PartSort1(a, left, right);//挖坑法
//int KeyIndex = PartSort2(a, left, right);//左右指針法
//int KeyIndex = PartSort3(a, left, right);//前后指針法
if (KeyIndex - left - 1 > 10)
{
QuickSort(a, left, KeyIndex - 1);
}
else {
InsertSort(a + left, KeyIndex - 1 - left+1);//直接插入排序
}
if (right - KeyIndex - 1 > 10)
{
QuickSort(a, KeyIndex + 1, right);
}
else {
InsertSort(a + KeyIndex + 1, right - (KeyIndex + 1) + 1);//直接插入排序
}
}
冒泡排序
冒泡排序是交換排序的一種。
所謂交換,就是根據(jù)序列中兩個(gè)記錄鍵值的比較結(jié)果來對(duì)換這兩個(gè)記錄在序列中的位
置,交換排序的特點(diǎn)是:將鍵值較大的記錄向序列的尾部移動(dòng),鍵值較小的記錄向序列的前部移
動(dòng)
思路分析
1.將第一個(gè)數(shù)與第二個(gè)數(shù)比較,大者則交換順序。
2.然后比較對(duì)象向后移動(dòng)一位,繼續(xù)上一步操作。
3.直到比較完成為止,這樣最大的數(shù)就排到最后一位。
然后再重復(fù)上面的操作,最后所以的數(shù)都排好,這就是冒泡排序。
代碼實(shí)現(xiàn)
這里的flag是優(yōu)化了基礎(chǔ)的冒泡排序,提高了時(shí)間效率。
利用flag判斷每次輪回序列是否已經(jīng)排序好,這樣可以避免重復(fù)的排序。
void BubbleSort(int* a,int n)
{
int end = n - 1;
for (int j = 0; j < end; j++)
{
int flag = 0;
for (int i = 1; i <= end-j; i++)
{
if (a[i - 1] > a[i])
{
Swap(&a[i - 1], &a[i]);
flag = 1;
}
}
if (flag == 0)
{
break;
}
}
}
好啦,這就是今天學(xué)習(xí)的分享啦!看到希望大家的三連呀!
如果有不當(dāng)之處,歡迎大佬指正!
柚子快報(bào)激活碼778899分享:算法 【數(shù)據(jù)結(jié)構(gòu)】快速排序
http://yzkb.51969.com/
精彩文章