快速排序

快速排序的基本思想:通过一趟排序将一组数据分割成独立的两个部分,其中一部分都是比关键字小的数据,另一部分是比关键字大的数据。然后将这两部分再次排序,最终达到序列有序的目的。

从两头开始排序

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));
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值