基数排序和希尔排序,堆排

1、基数排序

 基数排序是一种不进行比较的稳定的排序方法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。在这里插入图片描述

void radixsort(vector<int>& v, int n) //基数排序
{
	//找到最大的数,计算出分配次数
	int maxv = *max_element(v.begin(), v.end());
	int k = to_string(maxv).size();
	//声明tmp数组,用于收集数据
	vector<int> tmp(n, 0);
	//声明桶的个数
	vector<int> backet(10, 0);
	int base = 1;
	for (int i = 0; i < k; i++) {
		//记录数据到桶
		backet.assign(10, 0);
		for (int i = 0; i < n; i++)
		{
			int p = (v[i] / base) % 10;
			backet[p]++;
		}
		for (int i = 1; i < 10; i++)
		{
			backet[i] += backet[i - 1];
		}
		//收集数据
		for (int i = n-1; i >= 0; i--)
		{
			int p = (v[i] / base) % 10;
			tmp[backet[p] - 1] = v[i];
			backet[p]--;
		}
		for (int i = 0; i < n; i++)
			v[i] = tmp[i];
		base *= 10;
	}
}

注意以上代码不适合排序负数

2、希尔排序

 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。
 希尔排序是基于插入排序的以下两点性质而提出改进方法的:
 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;
 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。
先写个插入排序,然后直接在上面改动

void insert(vector<int>&v)
{
	int n = v.size() - 1;
	for (int i = 1; i <= n; i++)
	{
		int j = i - 1;
		int x = v[i];
		while (j >= 0 && v[j] > x)
		{
			v[j + 1] = v[j];
			j--;
		}
		v[j+1] = x;
	}
}
void shellsort(vector<int>&v)
{
	int n = v.size() - 1;
	int gap = n / 2;
	while (gap >= 1)
	{
		for (int i = gap; i <= n; i++)
		{
			int j = i - gap;
			int x = v[i];
			while (j >= 0 && v[j] > x)
			{
				v[j + gap] = v[j];
				j-= gap;
			}
			v[j + gap] = x;
		}
		gap /= 2;
	}
}

3、堆排序

大根堆 从小到大排列,建立大根堆


void adjustdown(vector<int>& v,int parent,int len)
{
	int n = v.size();
	int child = 2 * parent + 1;
	while (child < len)
	{
		if (child+1< len && v[child] < v[child + 1])
			child++;
		if (v[parent] < v[child])
			swap(v[parent], v[child]);
		else if (v[parent] == v[child])
			break;
		parent = child;
		child = 2 * parent + 1;
	}
}
int main()
{
	vector<int> v = {- 2,3,1,5,7,4,84,6 };
	//建堆
	int n = v.size();
	for (int i = n / 2; i >= 0; i--)
	{
		adjustdown(v, i,n);
	}
	for (int i = n - 1; i > 0; i--)
	{
		swap(v[0], v[i]);
		adjustdown(v, 0,i);
	}
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值