快排算法,优化,非递归实现以及链表的快排

快速排序算法

思路:左右指针加二分递归

void QuickSort(vector<int>&arr, int left, int right)
{
	if (left >= right)
		return; 
  	int i = left;
  	int j = right;
  	while (i < j)//左右指针相向遍历交换
  	{
  		while (arr[j] > arr[left] && i < j)//最左侧数作为基准数
  		{
  			j--;
		}
		while (arr[i] < arr[left] && i < j)//最左侧数作为基准数
  		{
  			i++;
		}
		if (i < j)
		{
			swap(arr[i],arr[j]);
		}
	}
	swap(arr[left],arr[i]);
	QuickSort(arr, left, i - 1);
	QuickSort(arr, i + 1, right);
	return;
}

快速排序算法的优化

三数取中值优化基准数查找 避免数组基本有序导致复杂度O(n^2)

int GetMid(vector<int>&arr, int left, int right)//三数取中值
{
    int mid = left + ((right - left)>>1);
    if (arr[left] <= arr[right])
    {
        if (arr[mid] <  arr[left])
            return left;
        else if (arr[mid] > arr[right])
            return right;
        else
            return mid;
    }
    else
    {
        if (arr[mid] < arr[right])
            return right;
        else if (arr[mid] > arr[left])
            return left;
        else
            return mid;
    }
}
void QuickSort(vector<int>&arr, int left, int right)
{
	if (left >= right)
		return; 
	int mid = GetMid(arr,left,right);
    swap(arr[mid],arr[left]);
  	int i = left;
  	int j = right;
  	while (i < j)//双指针相向遍历交换
  	{
  		while (arr[j] > arr[left] && i < j)//最左侧数作为基准数
  		{
  			j--;
		}
		while (arr[i] < arr[left] && i < j)//最左侧数作为基准数
  		{
  			i++;
		}
		if (i < j)
		{
			swap(arr[i],arr[j]);
		}
	}
	swap(arr[left],arr[i]);
	QuickSort(arr, left, i - 1);
	QuickSort(arr, i + 1, right);
	return;
}

非递归实现

通过栈来模拟递归过程

void QuickSort(vector<int>&arr, int left, int right)
{
	stack<int> s;
	s.push(left);
	s.push(right);//后入的right,所以要先拿right
	while(!s.empty)//栈不为空
	{
		int r = s.top();
		s.pop();
		int l = s.top();
		s.pop();
		
		int i = l;
	  	int j = r;
	  	while (i < j)//左右指针相向遍历交换
	  	{
	  		while (arr[j] > arr[l] && i < j)//最左侧数作为基准数
	  		{
	  			j--;
			}
			while (arr[i] < arr[l] && i < j)//最左侧数作为基准数
	  		{
	  			i++;
			}
			if (i < j)
			{
				swap(arr[i], arr[j]);
			}
		}
		swap(arr[l], arr[i]);
		
		if ((i - 1) > l)//左子序列
		{
			s.push(l);
			s.push(index - 1);
		}
		if ((i + 1) < r)//右子序列
		{
			s.push(index + 1);
			s.push(r);
		}
	}
}

链表的快排

前后指针加二分递归

struct ListNode
{
	int val;
	ListNode* next;
	ListNode(int v)
		: val(v)
		, next(nullptr)
	{}
};
 
ListNode* GetPartion(ListNode* pBegin, ListNode* pEnd)
{
	int baseVal = pBegin->val;
	ListNode* p = pBegin;
	ListNode* q = p->next;
 
	while (q != pEnd)//前后指针遍历
	{
		if (q->val < baseVal)
		{
			p = p->next;
			swap(p->val,q->val);
		}
		q = q->next;
	}
	swap(p->val, pBegin->val);
	return p;
}
 
void QuickSort(ListNode* pBeign, ListNode* pEnd)
{
	if (pBeign != pEnd)
	{
		ListNode* partion = GetPartion(pBeign,pEnd);
		QuickSort(pBeign, partion);
		QuickSort(partion->next, pEnd);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值