按名次排序并原地重排

一个元素在序列当中的名次,例如{4,3,9,3,7},最左边出现的3 名次记成0,后面出现的3记1,从小到大从左到右可以将名次记为{2,0,4,1,3}。现在需要对于一组序列进行名次计算,并根据名次对于原序列重新进行排列。这次的方法使用的是原地重排法。

原地重排法介绍:i是循环变量,r[i]存放的是a[i]数组里面的名次,当i!=r[i]时,将r[i]与r[r[i]]交换,对应的a[i]也进行交换,当i=r[i]时,i++进入下一个。

i=0,1,2,3,4

r[i]=2,0,4,1,3

a[i]=4,3,9,3,7

重排1次时:

i=0,1,2,3,4

r[i]=4,0,2,1,3

a[i]=9,3,4,3,7

重排2次时:

i=0,1,2,3,4

r[i]=3,0,2,1,4

a[i]=7,3,4,3,9

重排3次时:

i=0,1,2,3,4

r[i]=1,0,2,3,4

a[i]=3,3,4,7,9

重排4次时:

i=0,1,2,3,4

r[i]=0,1,2,3,4

a[i]=3,3,4,7,9

然后遍历一遍正好满足所求。

具体见代码:

#include<iostream>
using namespace std;
template<class T>
void swap(T *a,T *b)         //交换
{
	T temp;
	temp=a;
	a=b;
	b=temp;
}
template<class T>
void rearrange(T a[],T r[],int n)     //原地重排法
{
	for(int i=0;i<n;i++)
		while(r[i]!=i)
		{
			swap(a[i],a[r[i]]);
			swap(r[i],r[r[i]]);
		}
}
template<class T>
void range(T a[],T r[],int n)
{
	for(int i=0;i<n;i++)
		r[i]=0;
	for(int i=0;i<n;i++)
		for(int j=0;j<i;j++)
			if(a[j]>a[i])r[j]++;
			else r[i]++;
}
int main()
{
	int a[ ]={'d','a','e','f','c','b'};
	int r[10];
	range(a,r,6);
	for(int i=0;i<6;i++)
		cout<<r[i];
	cout<<'\n';
	rearrange(a,r,5);
	for(int i=0;i<6;i++)
		printf("%c",a[i]);
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值