您的位置:首页 > 其它

算法导论,习题8-2,计数排序原址排序

2014-07-09 17:11 148 查看
计数排序:

n 表示 n个数

k 表示n个数的最大值为k-1

书上用伪代码呈现的计数排序是稳定的,但是需要两个辅助数组,一个是n大小,一个k大小, 习题8-2的e小题需要写出只用一个k大小的辅助数组就可以的计数排序,本以为很简单,结果想了很久没想出来,最后还是看了网上的代码,真是羞愧,

下面是代码
#include<iostream>
#include<fstream>
#include<cstdlib>
#include "MyTimer.h"
#include<ctime>
using namespace std;
const int n=100;
int *c=new int
;
int *b=new int
;
void countint_sort(int a[],int n){//计数排序,需要k的临时存储 n的临时储存
for(int i=0;i!=n;++i){//初始化0
    c[i]=0;
}
for(int j=0;j!=n;++j){//统计a中数字i=a[j]出现的次数 用c[i]存储
    c[a[j]]=c[a[j]]+1;
}

for(int i=1;i!=n;++i){// 通过循环 计算出比i小的数的个数,存储在c[i]中
    c[i]=c[i]+c[i-1];
}

for(int j=n-1;j!=-1;--j){//从a数组最右边的数开始,m=a[j] ,比m小的数一共有 c[m]个,然后把m赋值到b数组的c[m]-1的位置上去
    b[c[a[j]]-1]=a[j];
    c[a[j]]=c[a[j]]-1;//如果有重复数组 则比这个数小的数减少1
}

}

void countint_sort2(int a[],int n){//计数排序,需要k的临时存储 可以说是原址排序
for(int i=0;i!=n;++i){//初始化0
    c[i]=0;
}
for(int j=0;j!=n;++j){//统计a中数字i=a[j]出现的次数 用c[i]存储
    c[a[j]]=c[a[j]]+1;
}

for(int i=1;i!=n;++i){// 通过循环 计算出比i小的数的个数,存储在c[i]中
    c[i]=c[i]+c[i-1];
}
for(int i=0;i!=n;++i){ //先把a数组全部变为0,这里增加了一次循环,但是节省了内存
    a[i]=0;
}
for(int i=n-1;i!=0;--i){//这里的主要思想就是,从c[i]的最高位置出发, 数字为i 如c[i]=c[i-1]说明i这个数在原数组里一个都不存在,c[i]比c[i-1]大多数,i就存在几次 ,这个大家可以画个图想清楚,由于i只循环的1 所以对于i=0,上面的循环置a数组全为0就起作用了,
while(c[i]!=c[i-1]){  
    a[c[i]-1]=i;
    c[i]--;
}
}

}

int *a=new int
;

int main(){

srand(time(NULL));
for(long int i=0;i!=n;++i){
    a[i]=rand()%n;//产生数 0~n-1  所以c数组需要n大小
}

for(int i=0;i!=n;++i){
    cout<<a[i]<<"  ";
}cout<<endl;cout<<endl;
MyTimer mt;
mt.Start();
countint_sort(a,n);
mt.End();
cout<<mt.costTime<<"us"<<endl;
for(int i=0;i!=n;++i){
    cout<<b[i]<<"  ";
}

cout<<endl;cout<<endl;

countint_sort2(a,n);
for(int i=0;i!=n;++i){
    cout<<a[i]<<"  ";
}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: