《数据结构c++》-第十二章

目录

排序算法

快排

选取与中位数

众数

归并向量的中位数

k-选取问题

希尔排序(shellsort)



排序算法


快排

快排与归并的区别:两者均属于分治算法 ,然而归并是归并需要O(n),快排是问题划分需要O(n)。快排的问题在于划分出来的子问题并不一定均衡,其最坏情况下O(nlogn)的复杂度,然而其大多数情况下性能均强于别的排序算法。

思路:选取一个pivot,使得pivot将数组分为两个部分,pivot前的均小于pivot,后的均大于pivot

数组 【lo,hi】->选取pivot,从两端交替比较与pivot的大小,将pivot放在其应该的位置上,返回这个位置mi->将远问题分解为[lo,mi]&[mi+1,hi]->直到hi-lo<2终止。

int  partition(vector<double>& xx, int lo, int hi)
{
	swap(xx[lo], xx[lo + rand() % (hi - lo+1)]);
	double pivot = xx[lo];
	while (lo<hi)
	{
		while ((lo < hi) && (pivot <= xx[hi]))
			hi--;
		xx[lo] = xx[hi];
		while ((lo < hi) && (xx[lo] <= pivot))
			lo++;
		xx[hi] = xx[lo];
	}
	xx[lo] = pivot;
	return lo;
}
void quicksort(vector<double>& v_d, int lo, int hi)//lo hi为数组首位角标
{
	if (hi - lo < 2) return;
	int mi = partition( v_d, lo, hi);
	quicksort(v_d, lo, mi);
	quicksort(v_d, mi + 1, hi);
}

选取与中位数

众数

A中有一半以上的元素数值都是m,则m为A的众数。

思路:

选出候选众数maj

核实maj是否为众数

int maj_find(vector<int> A)
{
	int maj;
	for (int c = 0, i = 0; i != A.size(); i++)
	{
		if (0 == c)
		{
			maj = A[i]; c = 1;
		}
		else
		{
			maj == A[i] ? c++ : c--;
		}
	}
	return maj;
}
bool maj_check(vector<int>A, int maj)
{
	int counts(0);
	for (auto a : A)
		if (a == maj)
			counts++;
	return 2 * counts > A.size();
}
bool maj_fun(vector<int> A, int & maj)
{
	maj=maj_find(A);
	return maj_check(A, maj);
}

归并向量的中位数

归并两个有序向量时候,可以比较两个向量的中间元素大小,可将问题规模减半。递归深度不超过logn 时间复杂度O(logn)

k-选取问题

  1. 构建n大小的小顶堆,经过k次dlmin,O(n)+kO(logn)
  2. 任取k个构建大顶堆,依次插入后维护,O(k)+2(n-k)O(logk)
  3. 构建一个n-k的小顶堆,k的大顶堆,然后反复比较堆顶元素O(n-k)+O(k)+min(k,n-k)*2*(O(lgk+lg(n-k)))

 

希尔排序(shellsort)

将A[]->B[][]

B[i][j]=A[iw+j]

w1<w2<...<size

将A分为w1列,然后逐行排序,排完之后再将其分为w2。。。。迭代直到w>size

 

shell序列[w1,w2,w3...]尽量互为素数

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值