计数排序----C++

emmmC++真的有些绝望,在实现上要比Java难

计数排序:

其核心思想是选择。

温故--选排:

我们知道,选择排序是第n次选出第n大的值放在a[n-1](数组从0开始,若为n个元素,则最后一个为a[n-1])的位置---即数组的最大值放在a[0],第二大放a[1]...第n大在a[n-1].

上一篇博客有写。链接:https://mp.csdn.net/postedit/84593100

知新--计数排序:

计数?计什么数?记录比自己数值小(或大)的元素个数。(代码从小到大)

有一群人,他们数量为n,要按身高从小到大排队站好。对任何一个人而言,如果有count个人比自己矮,那么自己就应该在count+1的位置站着。

同理,我们换到数组,注意数组从零开始,到n-1结束。那么对于每一个值而言,比他小的有count,那他的位置就是count。

代码1.0(错误版本)

先总结一下自己犯的错误:

问题在代码中用注释标出了

先说一下问题明显的问题2:

count的问题,之前强调过,数组从0---n-1,那么对于每一个值而言,比他小的有count个,那他的位置就是count,而不是count+1.

比较致命的问题1(当时还找了好一会):

出现这个问题是由于我最开始的思路错了:

让我发挥一下洗脑大法:

1.找出count的的过程:第一重for循环是提供每一个值i,第二重循环是找出比i小的个数count,到这还是无懈可击的。

2.交换:既然比他小的值有count个,那他的位置就是count。那么我就交换a[i]和a[count]的位置,这样就保证了它的位置的正确性。

如果遇到一样的值怎么办(如int a[4]={1,8,9,8}有两个8)?

我们需要判断这个位置是否被人占了?被人占了会怎么样?被占用了就会出现你要放在这的值==这个位置上的值,那怎么办?挨着这里坐下就大功告成了。如果你问:那如果有三个一样的怎么办?很简单,while循环判断,这两个值不等时才可以跳出。

无奖竞猜:你发现问题了吗?

 

 

答案就是我不能这样去交换两个位置的值。

举个栗子:

int a={5,4,3,2,1};

可以发现a[0]=5,比他小的有四个,那么a[0]和a[4]交换位置,就变成了a={1,4,3,2,5}

这样看上去好像没有毛病,但青关注此时的i值,找过第一次后,i从0变到1.这就大事不妙了,变到1之后的i会找比a[1]小的数据的

个数----就是小于4的个数。

那么新的a[0],也就是1,他就不会进行查找了。

你可能会问·:“说不定还有有数和0位置交换呢?”

“这个例子已经告诉你了,1就是最小的,不会有人再来找他换房间了”

 

错误代码如下❌:

#include<iostream>
using namespace std;

void sort(int* a,int len,int *b){
	
	for(int i=0;i<len;++i){
		//寻找每一个元素i的count 
		int count=0;
		for(int j=0;(j<len);j++){
		    if((a[j]<a[i])){
			count++;
		}
		}
		
//问题1		cout<<count<<endl;
//问题2		if(b[count]==a[i]){		
	  	    while(a[i]==a[count+1]){
			i++;
		}
//问题1    	int t=a[i];
//问题1         a[i]=a[count+1];
//问题1		a[count+1]=t;
	
	}
}

int main(){
	int a[12]={100,4,44,6,8,2,3,41,5,44,44,99};
	int b[12]={0,0,0,0,0,0,0,0,0,0,0,0};
	int len=sizeof(a)/sizeof(a[0]); 
	
	cout<<"before :"<<endl;
	for(int i=0;i<len;++i){
		cout<<a[i]<<"  ";
	}
	cout<<endl;
	sort(a,len,b);
	cout<<"after :"<<endl;
	for(int i=0;i<len;++i){
		cout<<b[i]<<"  ";
	}
	cout<<endl;
	return 0;
} 

 

代码2.0(正确版本)

#include<iostream>
using namespace std;

void sort(int* a,int len,int *b){
	
	for(int i=0;i<len;++i){
		//寻找每一个元素i的count 
		int count=0;
		for(int j=0;(j<len);j++){
		    if((a[j]<a[i])){
		        count++;
		}
		while(b[count]==a[i]){
		    count++;
		}
		b[count]=a[i];
	}
}

int main(){
	int a[12]={100,4,44,6,8,2,3,41,5,44,44,99};
	int b[12]={0,0,0,0,0,0,0,0,0,0,0,0};
	int len=sizeof(a)/sizeof(a[0]); 
	
	cout<<"before :"<<endl;
	for(int i=0;i<len;++i){
		cout<<a[i]<<"  ";
	}
	cout<<endl;
	sort(a,len,b);
	cout<<"after :"<<endl;
	for(int i=0;i<len;++i){
		cout<<b[i]<<"  ";
	}
	cout<<endl;
	return 0;
} 

结果展示:

 

 

推荐一个可视化的数据结构与算法是网站(emm动图演示排序,链表会更容易些吧,还提供代码运行处)

https://visualgo.net/en 

值得一乐 他的中文版缩写是zh(黑人问号脸,英文en)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值