快速排序,递归,以第一个值为支点,最后一个值为支点,分别从不同的方向开始遍历 C/C++

#include<iostream>

using namespace std;

/**
* 快速排序递归解法
**/
void swap(int* a,int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
// 情况一:以右值为支点,从左开始比较
void quick_sort(int unsortedNums[],int start,int end)
{
// 排序结束条件,递归的子序列只有一个元素或者没有元素
if(start>=end) return;

int pivot = unsortedNums[end]; // 支点
int left = start,right = end;

while(left < right)
{
while(unsortedNums[left] < pivot && left < right) left++; // 先左
while(unsortedNums[right] >= pivot && left < right) right--;
swap(&unsortedNums[left],&unsortedNums[right]);
}
/**
* 一轮交换后,左指针最后指向的元素 只有两种情况:一是指向一个比支点大的元素(左指针要么在比支点大的元素停下来等右指针和自己重合,要么自己走到和右指针重合,都是大于支点的元素);二是指向支点(序列元素全部小于支点)
*/

//这里不需要判断左值和支点的大小,因为他们只有值大于或者位置等于的关系, 交换左指针和支点,这一步是使支点到整个序列正确的位置,这个位置也是排序后的支点的位置。
swap(&unsortedNums[left],&unsortedNums[end]);

// 支点已经放在了正确的位置,不需要让支点参与递归了。
quick_sort(unsortedNums,start,left-1);
quick_sort(unsortedNums,left + 1,end);

}


// 情况二:以右值为支点,从右开始比较
void quick_sort_1(int unsortedNums[],int start,int end)
{
if(start>=end) return;

int pivot = unsortedNums[end];// 支点
int left = start,right = end;

while(left < right)
{
while(unsortedNums[right] >= pivot && left < right) right--; // 先右
while(unsortedNums[left] < pivot && left < right) left++;
swap(&unsortedNums[left],&unsortedNums[right]);
}
// 一轮交换后,右指针最后指向的元素,有两种情况:一是指向一个比支点小的元素(右指针要么在比支点小的元素停下来等左指针和自己重合,要门自己走到和左指针重合,都是小于支点),二是指向最左元素(可能大于或者小于支点)

//这里需要判断右指针与支点的大小,如果是比支点小的话,那么可以跳过这个位置,因为位置一定是在新的数列左边。
if(unsortedNums[right]>=pivot)
swap(unsortedNums[right],unsortedNums[end]);
else right++;

//right的位置不一定是最终序列的位置,所以这里再次递归的时候要包含right
quick_sort_1(unsortedNums,start,right-1);
quick_sort_1(unsortedNums,right,end);
}


// 情况三:以左值为支点,从右开始比较
void quick_sort_2(int unsortedNums[],int start,int end)
{
if(start>=end) return;
int pivot = unsortedNums[start];
int left = start,right = end;
while(left<right)
{
while(unsortedNums[right]>pivot && left < right) right--;
while(unsortedNums[left]<=pivot && left < right) left++;
swap(&unsortedNums[left],&unsortedNums[right]);
}
// 由指针一定停在比比支点小的地方,或者和支点同一个位置,交换由指针和支点的位置
swap(unsortedNums[right],unsortedNums[start]);
// 支点一定放在了最终序列的确定位置上。所以可以在递归中可以省略这个值。

quick_sort_2(unsortedNums,start,right-1);
quick_sort_2(unsortedNums,right+1,end);
}

// 情况四:以左值为支点,从左开始比较
void quick_sort_3(int unsortedNums[],int start,int end)
{
if(start>=end) return;
int pivot = unsortedNums[start];
int left = start,right = end;

while(left<right)
{
while(unsortedNums[left] <= pivot && left < right) left++;
while(unsortedNums[right] > pivot && left < right) right++;
swap(&unsortedNums[left],&unsortedNums[right]);
}
// 左指针如果比支点小,那么交换两者,那么支点就放在了最终序列的确定位置上,
if(unsortedNums[left] <= pivot) swap(&unsortedNums[left],&unsortedNums[start]);
else left--; // 如果左值指针比支点大,那么左值往前推一步,因为当前的左值指针一定在后半序列中。在最终序列的位置未知,所以递归不能省略这个值。
quick_sort_3(unsortedNums,start,left);
quick_sort_3(unsortedNums,left+1,end);
}


int main()
{
int unsortedNums[] = {3,5,2,9,4,6,8,2,1,2,3,9,5,6,7,8,10,11,2,3,5,6,7,8,5};
int length = 25;

int unsortedNums1[] ={10,9,8,7,6,5,4,3,2};
// int unsortedNums1[] = {0,0,10};
cout<<"before sorted:"<<endl;
for(int num : unsortedNums1) cout<< "elements:"<<num << endl;
// quick_sort(unsortedNums1,0,10);
quick_sort_1(unsortedNums1,0,8);

cout<<"after sorted:"<<endl;
for(int num : unsortedNums1) cout<<"elements:"<<num<<endl;

int unsortedNums2[] ={6,3,4,5};
cout<<"before sorted:"<<endl;
for(int num : unsortedNums2) cout<< "elements:"<<num << endl;
quick_sort(unsortedNums2,0,3);
// quick_sort_1(unsortedNums1,0,10);

cout<<"after sorted:"<<endl;
for(int num : unsortedNums2) cout<<"elements:"<<num<<endl;

int unsortedNums3[] ={10,9,8,7,6,5,4,3,2};
// int unsortedNums1[] = {0,0,10};
cout<<"before sorted:"<<endl;
for(int num : unsortedNums3) cout<< "elements:"<<num << endl;
// quick_sort(unsortedNums1,0,10);
quick_sort_1(unsortedNums3,0,8);

cout<<"after sorted:"<<endl;
for(int num : unsortedNums3) cout<<"elements:"<<num<<endl;

int unsortedNums4[] ={10,9,8,7,6,5,4,3,2};
// int unsortedNums1[] = {0,0,10};
cout<<"before sorted:"<<endl;
for(int num : unsortedNums4) cout<< "elements:"<<num << endl;
// quick_sort(unsortedNums1,0,10);
quick_sort_1(unsortedNums4,0,8);

cout<<"after sorted:"<<endl;
for(int num : unsortedNums4) cout<<"elements:"<<num<<endl;


}

posted @ 2022-05-19 14:08  danieldai  阅读(37)  评论(0编辑  收藏  举报