排序算法(五)——快速排序
快速排序和归并排序一样都是基于递归求解,将问题划分成两个子问题,时间复杂度都是O(nlogn),不同的是快速排序的是基于元素与选定x的大小关系来划分。PS:一般我们选定序列第一个元素作为选定x。
示例序列:9 4 8 6 5 2 1 3 7 10
将9作为选定标准进行划分,小于等于9的都放在左边,大于9的都放在右边(考虑到会出现重复元素的情况)
划分子序列:设置两个指针low和high,分别指向两端。
从右边开始(注意一定要从右边开始)找到不满足>9的元素,第一遍找到7;
在从左边开始,找到不满足<=9的元素(等号必须出现在这里,因为最后当high==low的时候,要将9和list[high]进行交换,从而9的两边就能划分开了),没有找到,low和high都指向7,
将9和7进行交换,得到【7 4 8 6 5 2 1 3】 9 【10】,然后将9两边的两个子序列继续进行排序,当只有一个元素的时候,直接return,
依次递归下去。
示例代码:
#include <iostream>
#include <ctime>
using namespace std;
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
int Quick_sort_index(int list[],int begin,int end)
{
int low=begin,high=end;
int num=list[begin];
while(low<high)
{
while(low<high&&list[high]>num)
high--;
while(low<high&&list[low]<=num)
low++;
if(list[low]!=list[high])
swap(list[low],list[high]);
}
if(list[high]!=num)
swap(list[high],list[begin]);
return high;
}
void Quick_sort(int list[],int begin,int end)
{
if(begin>=end)
return;
int index=Quick_sort_index(list,begin,end);
Quick_sort(list,begin,index-1);
Quick_sort(list,index+1,end);
}
int main()
{
int list[10]={1,23,345,12,6,56,45,444,23,46};
Quick_sort(list,0,9);
for(int i=0;i<10;i++)
cout<<list[i]<<" ";
cout<<endl;
system("pause");
}
另外递归和非递归(循环)的代码可参考:
https://www.cnblogs.com/ljy2013/p/4003412.html
pritation函数:
int Pritation(int* a, int left, int right)
{
if (a == NULL || left < 0 || right <= 0||left>=right)
return -1;
int priot = a[left];
int i = left, j = right;
while (i < j)
{
while (i < j&&a[j] >= priot)
j--;
if(i<j)
a[i]=a[j];
while (i < j&&a[i] <= priot)
i++;
if(i<j)
a[j]=a[i];
}
a[i] = priot;
return i;
}
递归代码:
void QuickSort(int *a, int left,int right)
{
if (a == NULL || left < 0 || right <= 0 || left>right)
return;
int k = Pritation(a, i, j);
//下面是递归实现的代码
if (k > left)
QuickSort(a, left, k - 1);
if (k < right)
QuickSort(a, k + 1, right);
}
非递归代码:
void QuickSort(int *a, int left,int right)
{
if (a == NULL || left < 0 || right <= 0 || left>right)
return;
stack<int>temp;
int i, j;
//(注意保存顺序)先将初始状态的左右指针压栈
temp.push(right);//先存右指针
temp.push(left);//再存左指针
while (!temp.empty())
{
i = temp.top();//先弹出左指针
temp.pop();
j = temp.top();//再弹出右指针
temp.pop();
if (i < j)
{
int k = Pritation(a, i, j);
if (k > i)
{
temp.push(k - 1);//保存中间变量
temp.push(i); //保存中间变量
}
if (j > k)
{
temp.push(j);
temp.push(k + 1);
}
}
}
}
浙公网安备 33010602011771号