排序算法:堆排,快排的实现(快排的三种实现方法以及快排的优化)


1. 堆排

升序建大堆,逆序建小堆,先建堆,堆建好之后,将堆中最后一个元素和第一元素互换,然后执行向下调整算法进行调堆,最终实现相应的顺序。

void AdjustDown(vector<int>& iv, int pos,int n)
{
	int parent = pos;
	int child = pos * 2 + 1;
	while (child < n)
	{
		if (child + 1 < n && iv[child] < iv[child + 1])
			++child;
		if (iv[parent] < iv[child])
		{
			swap(iv[parent], iv[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
			break;
	}
}

void HeapSort(vector<int>& iv)
{
	for (int i = (iv.size()-1) >> 1 ; i >= 0; --i)
	{
		AdjustDown(iv, i,iv.size());
	}

	int end = iv.size() - 1;
	while (end >= 0)
	{
		swap(iv[end], iv[0]);
		AdjustDown(iv, 0,end);
		--end;
	}
}

int main()
{
	vector<int> iv = { 2,5,6,7,8,9 };
	HeapSort(iv);
	for (const auto& e : iv)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

2. 快排

2.1 双指针法

void _QuickSort(vector<int>& iv, int left, int right)
{
	if (left >= right)
		return;
	int begin = left;
	int end = right;
	int key = left;

	while (begin < end)
	{
		while (begin < end && iv[end] >= iv[key])
			--end;
		while (begin < end && iv[begin] <= iv[key])
			++begin;
		swap(iv[end], iv[begin]);
	}

	swap(iv[key], iv[begin]);
	key = begin;

	_QuickSort(iv, left, key - 1);
	_QuickSort(iv, key + 1,right);
}

void QuickSort(vector<int>& iv)
{
	_QuickSort(iv, 0, iv.size()-1);
}

2.2 挖坑法

void _QuickSort(vector<int>& iv, int left, int right)
{
	if (left >= right)
		return;

	int begin = left;
	int hole = iv[left];
	int end = right;

	while (begin < end)
	{
		while (begin < end && iv[end] >= hole)
			--end;
		iv[begin] = iv[end];
		while (begin < end && iv[begin] <= hole)
			++begin;
		iv[end] = iv[begin];
	}

	iv[begin] = hole;
	int key = begin;

	_QuickSort(iv, left, key - 1);
	_QuickSort(iv, key + 1, right);

}

2.3 前后指针法

void _QuickSort(vector<int>& iv, int left, int right)
{
	if (left >= right)
		return;

	int next = left;
	int key = right;
	int prev = left - 1;

	while (next != key)
	{
		if (iv[next] < iv[key] && ++prev != next)
		{
			swap(iv[next], iv[prev]);
		}
		++next;
	}

	swap(iv[key], iv[++prev]);
	key = prev;

	_QuickSort(iv, left, key - 1);
	_QuickSort(iv, key + 1, right);
}

2.4 非递归

void _QuickSort(vector<int>& iv, int left, int right)
{
	stack<int> st;
	st.push(left);
	st.push(right);

	while (!st.empty())
	{
		int r = st.top();
		st.pop();
		int l = st.top();
		st.pop();

		int end = r;
		int begin = l;
	

		int hole = iv[begin];
		while (begin < end)
		{
			while (begin < end && iv[end] >= hole)
				--end;
			iv[begin] = iv[end];
			while (begin < end && iv[begin] <= hole)
				++begin;
			iv[end] = iv[begin];
		}

		iv[begin] = hole;
		int key = begin;

		if (key - 1 > l)
		{
			st.push(l);
			st.push(key - 1);
		}

		if (key + 1 < r)
		{
			st.push(key + 1);
			st.push(r);
		}
	}
}

2.5 快排的优化(三数取中+小区间优化)

三数取中

int getMidIndex(vector<int>& a,int left, int right)
{
    //首先求出mid的值
    int mid = (left + right) >> 1;
    //当left < mid时
    if(a[left] < a[mid])
    {
        //当mid < right 时,返回mid的值(位于中间)
        if(a[mid] < a[right])
        {
            return mid;
        }
        else if(a[right] < a[left])
        {
            return left;
        }
        else
        {
            return right;
        }
    }
    else //left >= mid
    {
        if(a[mid] > a[right])
        {
            return mid;
        }
        else if(a[left] < a[right])
        {
            return left;
        }
        else
        {
            return right;
        }
    }
}

小区间优化

//快排优化----最小区间优化
//当[left,right]的范围很小时,即数据量很小时,
//就直接使用插入排序,减少递归的次数(即相当于减少叶子节点的递归数目)
void InsertSort(vector<int>& iv)
{
	for (int i = 0; i < iv.size() - 1; ++i)
	{
		int end = i;

		int tmp = iv[end + 1];
		while (end >= 0)
		{
			if (iv[end] > tmp)
			{
				iv[end + 1] = iv[end];
				--end;
			}
			else
				break;
		}

		iv[end + 1] = tmp;
	}
}    

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值