小白进阶之线性排序算法之计数排序、基数排序和桶排序

线性排序算法主要有三个:计数排序、基数排序和桶排序。

计数排序:时间复杂度为O(n)。算法基本思路是:假设n个元素中的每个都是在0到k区间内的一个整数(其中k为某整数)。对于每个输入元素x,确定小于x的元素个数,利用这一信息,就可以直接把x放到它在输出数组中的位置了。

基数排序:时间复杂度为θ(d(n+k))(其中d表示d位数,n表示共有n个d位数,k表示 每位数都在0到k-1区间内)。算法的基本思路是:先按最低有效位进行排序,将相应数字放入指定容器中,再把所有数字合为一个数组,其中保持原来容器的顺序,即0号容器的数字放在1号容器之前,1号在2号之前。。。然后再次按照相同的方法对次低有效位对所有数字进行排序,直至所有d位数字都进行排序。

桶排序:时间复杂度为θ(n)。算法的基本思想是:假设输入的数字序列均在0到1范围内,一共n个数字,让b[n]变成一个空数字,然后把a[i]插入到b[b*a[i]]中,再对从0到n-1的每个b[i]进行插入排序,最后把b聚合在一起就可以了。在实现的时候,为了实现方便,我在插入时就进行了插入排序。

下面是代码:

linearSort.h

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct digit{//用于基数排序的结构体
	int c;
	struct digit *next;
};
typedef struct digitt{//用于桶排序的结构体
	double c;
	struct digitt *next;
};
void countingSort(int *a,int *b,int k,int n);//计数排序
void radixSort(int *a,int d,int n);//基数排序
void bucketSort(double *a,int n);//桶排序

linearSort.cpp

#include"linearSort.h"
void countingSort(int *a,int *b,int k,int n){
	int *c;
	c=(int *)malloc(sizeof(int)*(k+1));
	int i;
	for(i=0;i<=k;i++){
		c[i]=0;
	}
	for(i=0;i<n;i++){
		c[a[i]]+=1;
	}
	for(i=1;i<=k;i++){
		c[i]=c[i]+c[i-1];
	}
	for(i=n-1;i>=0;i--){
		b[c[a[i]]-1]=a[i];
		c[a[i]]=c[a[i]]-1;
	}
}
void radixSort(int *a,int d,int n){
	struct digit *dig[10];
	int i,j,t;
	for(i=0;i<d;i++){
		for(t=0;t<10;t++){
			dig[t]=(struct digit *)malloc(sizeof(struct digit));
			dig[t]=NULL;
		}
		int powq=(int)pow((double)10,i);
		for(j=0;j<n;j++){
			int temp=(a[j]/powq)%10;
			struct digit *p,*q;
			p=(struct digit *)malloc(sizeof(struct digit));
			p->c=a[j];
			p->next=NULL;
			q=(struct digit *)malloc(sizeof(struct digit));
			q=dig[temp];
			if(dig[temp]==NULL){
				dig[temp]=p;
			}
			else{
				while(q->next!=NULL){
					q=q->next;
				}
				q->next=p;
			}
		}
		int t=0;
		for(j=0;j<10;j++){
			struct digit *q=dig[j];
			while(q!=NULL){
				a[t]=q->c;
				q=q->next;
				t++;
			}
		}
	}
}
void bucketSort(double *a,int n){
	struct digitt **b=(struct digitt **)malloc(sizeof(struct digitt *)*n);
	int i;
	for(i=0;i<n;i++){
		b[i]=(struct digitt *)malloc(sizeof(struct digitt));
		b[i]=NULL;
	}	
	for(i=0;i<n;i++){
		int t=n*a[i];
		struct digitt *p,*q,*f;
		p=(struct digitt *)malloc(sizeof(struct digitt));
		q=(struct digitt *)malloc(sizeof(struct digitt));
		f=(struct digitt *)malloc(sizeof(struct digitt));
		p=b[t];
		q->c=a[i];
		q->next=NULL;
		if(b[t]==NULL){
			b[t]=q;
		}
		else{
			if(p->c>=a[i]){
				f=b[t];
				b[t]=q;
				b[t]->next=f;
			}
			else{
				while(p->c<=a[i]&&p->next!=NULL){
					f=p;
					p=p->next;
				}
				if(p->next==NULL&&p->c<a[i])
					p->next=q;
				else{
					f->next=q;
					q->next=p;
				}
			}
		}
	}
	int t=0;
	for(i=0;i<n;i++){
		struct digitt *p=(struct digitt *)malloc(sizeof(struct digitt));
		p=b[i];
		while(p!=NULL){
			a[t]=p->c;
			p=p->next;
			t++;
		}
	}
}

main.cpp

#include"linearSort.h"
int main(){
	int *a,*b,n,k,m;
	int i;
	printf("Please input the range of the array and the digit of the array and the number of the array:\n");
	scanf("%d %d %d",&k,&m,&n);
	a=(int *)malloc(sizeof(int)*n);
	b=(int *)malloc(sizeof(int)*n);
	printf("Please input the array:\n");
	for(i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	countingSort(a,b,k,n);
	printf("The counting sorted array is:\n");
	for(i=0;i<n;i++){
		printf("%d ",b[i]);
	}
	printf("\n");
	radixSort(a,m,n);
	printf("The radix sorted array is:\n");
	for(i=0;i<n;i++){
		printf("%d ",a[i]);
	}
	printf("\n");
	int e;
	printf("Please the number of the array:\n");
	scanf("%d",&e);
	double *c;
	c=(double *)malloc(sizeof(double)*e);
	printf("Please input the array:\n");
	for(i=0;i<e;i++){
		scanf("%lf",&c[i]);
	}
	bucketSort(c,e);
	printf("The bucket sorted array is:\n");
	for(i=0;i<e;i++){
		printf("%lf ",c[i]);
	}
	printf("\n");
	system("pause");
	return 0;
}

昨天写加调,一天,终于把这三个大名鼎鼎的线性排序算法全部搞好。表示各种链表、指针、结构体、数组,已经被搞的晕乎乎的,但是这也是最大的收获呀。嘿嘿。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值