快速排序的基本思想:通过一趟排序将一组数据分割成独立的两个部分,其中一部分都是比关键字小的数据,另一部分是比关键字大的数据。然后将这两部分再次排序,最终达到序列有序的目的。
从两头开始排序
int Partition(vector<int>& arr,int left,int right)
{
int i=left,int j=right;//让i和j分别指向数组的0号下标和n-1号下标
int tmp=arr[i];将0号下标作为关键值
while(i<j)//当i小于j时,说明数组中还有值
{
while(i<j&&arr[j]>tmp) --j;//如果j下标的值大于关键值的时候,j往前走
if(i<j) {arr[i]=arr[j];}
//当循环结束,说明找到了第一个比关键值小的值,让j下标的值覆盖掉掉i下标的值
while(i<j&&arr[i]<tmp) ++i;//如果i下标的值小于关键值的时候,i往后走
if(i<j) {arr[j]=arr[i];}
//当循环结束,说明找到了第一个比关键值大的值,将i下标的值覆盖掉j下标的值
}
arr[i]=tmp;//当循环结束,i下标的值为空或重复值,将tmp的值覆盖掉i下标的值,第一个排序完成
return i;//将i的下标返回,作为基准划分依据
}
从一头开始排序
思想:定义i和j,i指向left-1(空)下标,j指向0号下标,将0号下标作为基准值。当j号下标小于基准值的时候,j往后走。否则交换i+1和j下标的值。因为这里的i下标是从0-1号下标开始的。循环走完后,自i号下标开始,i前面的下标值都小于等于基准值,此时将基准值(tmp)与第i号下标交换。这时,第i号下标就是分界线。
int Partition(vector<int>& arr,int left,int right)
{
int i=left-1,int j=left;
int tmp=arr[j];
while(j<right)
{
if(arr[j]<=tmp)
{
std::swap(arr[i+1],arr[j]);
i++;
}
j++;
}
std::swap(arr[i],arr[left]);
return i;
}
对单链表进行快排
思想:同数组一端排序
typedef int ElemType;
typedef struct BtNode
{
BtNode* Next;
ElemType Data;
}BtNode,*BT;
BtNode* BuyNode()//申请一个节点
{
BtNode* s=(BtNode*)malloc(sizeof(BtNode));
if(s==NULL) exit(EXIT_FAILURE);
memset(s,0,sizeof(BtNode));
return s;
}
BtNode* InitList()
{
vector<int> arr = { 56,23,78,90,34,45,100,12,67,89 };
BtNode* head=BuyNode();
BtNode* p=head;
for(int i=0;i<arr.size();i++)
{
BtNode* s=BuyNode();
s->Data=arr[i];
s->Next=NULL;
p->Next=s;
p=p->Next;
}
return head;
}
BtNode* ListPartition(BtNode* left,BtNode* right)//带头结点的单链表
{
BtNode* i=left;//此时i指向的是头节点
BtNode* j=left->Next;//j指向的是链表第一个节点
ElemType tmp=j->Data;
while(j!=right)
{
if(j->Data<=tmp)
{
std::swap(i->Next->Data,j->Data);
i=i->Next;
}
j=j->Next;
}
std::swap(i->Data,left->Next->Data);
return i;
}
递归排序
void QuickPass(vector<int>& arr, int left, int right)
{
if(left<right)
{
int pos=Partition(arr,left,right);
QuickPass(arr,left,pos-1);
QuickPass(arr,pos+1,right);
}
}
非递归排序
void QuickPass(vector<int>& arr, int left, int right)
{
queue(int) qu;
qu.push(left),qu.push(right);//将两头入队列
while(!qu.empty())
{
left=qu.front();qu.pop();
right=qu.front();qu.pop();
int pos=Partiton(arr,left,right);
if(left<pos-1)
{
qu.push(left);
qu.push(pos-1);
}
if(pos+1<right)
{
qu.push(pos+1);
qu.push(right);
}
}
}
双对
void QuickPass(vector<int>& arr, int left, int right)
{
queue<std::pair<int,int>> qu;
std::pair<int,int> pa(left,right);
qu.push(pa);
while(!pa.empty())
{
pa=qu.front();qu.pop;
int pos=Partition(arr,pa.first,pa.second);
if(pa.first<pos-1)
{
qu.push(std::pair<int,int>(pa.first,pos-1));
}
if(pos+1<pa.second)
{
qu.push(std::pair<int,int> (pos+1,pa.second));
}
}
}