快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
6.1 算法描述
快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:
6.2 图例演示
【1】https://blog.csdn.net/MoreWindows/article/details/6684558
【2】https://blog.csdn.net/zpznba/article/details/83745205
这两种思路解法都很棒。
6.3 代码实现
版本1:挖坑填数
//挖坑的代码
int AdjustArray(int s[], int l, int r) //返回调整后基准数的位置
{
int i = l, j = r;
int x = s[l]; //s[l]即s[i]就是第一个坑
while (i < j)
{
// 从右向左找小于x的数来填s[i]
while(i < j && s[j] >= x)
j--;
if(i < j)
{
s[i] = s[j]; //将s[j]填到s[i]中,s[j]就形成了一个新的坑
i++;
}
// 从左向右找大于或等于x的数来填s[j]
while(i < j && s[i] < x)
i++;
if(i < j)
{
s[j] = s[i]; //将s[i]填到s[j]中,s[i]就形成了一个新的坑
j--;
}
}
//退出时,i等于j。将x填到这个坑中。
s[i] = x;
return i;
}
//分治的代码
void quick_sort1(int s[], int l, int r)
{
if (l < r)
{
int i = AdjustArray(s, l, r);//先成挖坑填数法调整s[]
quick_sort1(s, l, i - 1); // 递归调用
quick_sort1(s, i + 1, r);
}
}
版本2:
//快速排序
void quick_sort(int s[], int l, int r)
{
if (l < r)
{
//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
int i = l, j = r, x = s[l];
while (i < j)
{
while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
j--;
if(i < j)
s[i++] = s[j];
while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
s[j--] = s[i];
}
s[i] = x;
quick_sort(s, l, i - 1); // 递归调用
quick_sort(s, i + 1, r);
}
}
#include
using namespace std;
int Parition(int a[], int low,int high){
int pivot=a[high];
int i=low; //分区的点, a[low...i...high],i左边的数(不包含i)小于high,i右边的数大于high,然后将i位置的数和high的位置交换,
for(int j=low;j
参考文献:【1】https://blog.csdn.net/MoreWindows/article/details/6684558
【2】https://blog.csdn.net/zpznba/article/details/83745205
【3】https://blog.csdn.net/k_koris/article/details/80585979 很详细的参考图!!!
【4】https://blog.csdn.net/qq_36528114/article/details/78667034
递归的算法主要是在划分子区间,如果要非递归实现快排,只要使用一个栈来保存区间就可以了。
一般将递归程序改成非递归首先想到的就是使用栈,因为递归本身就是一个压栈的过程。
void QuickSort(int* array,int left,int right)
{
assert(array);
stack s;
s.push(left);
s.push(right);//后入的right,所以要先拿right
while(!s.empty)//栈不为空
{
int right = s.top();
s.pop();
int left = s.top();
s.pop();
int index = PartSort(array,left,right);
if((index - 1) > left)//左子序列
{
s.push(left);
s.push(index - 1);
}
if((index + 1) < right)//右子序列
{
s.push(index + 1);
s.push(right);
}
}
}