基数排序—递减

//基数排序:不是基于直接比较的排序算法(本文实现递减排序)
//每一位的取值只有10种情况,即:0-9,10是基数r
//第一趟以个位进行分配,因为是递减序列,所以收拾是从最大9开始,第一趟结束:得到按个位递减的序列
//第二趟以十位进行分配,由于第二趟的分配工作是基于第一趟,当两个十位的值相同时,按照个位递减
//第三趟以百位进行分配,若百位相同,按照十位递减,若十位还相同,按照个位递减
//要想得到递增排序,只需要先收集值更小的队列 
//基数为r,关键字由d元组构成,分配O(n),收集O(r),总共d趟分配收集,时间复杂度:O(d(n+r)),空间复杂度:O(r)
//具有稳定性
#include <iostream>
#include "stdlib.h"
using namespace std;
//全局变量 
int a[]={53,197,0,78,7,45,65,87,324,599,4,5,2,6};
int n=sizeof(a)/sizeof(int);
//比较元素的数据类型
typedef struct LinkNode{
	int data;
	struct LinkNode *next;
}LinkNode,*LinkList;

//链式队列,每个元素的数据类型是LinkNode
typedef struct{
	int len; 
	LinkNode *front,*rear;
}LinkQueue;

//单链表的初始化(带头结点) 
void initLinkList(LinkList &L){
	L=(LinkNode*)malloc(sizeof(LinkNode));	//创建头结点 
	L->next=NULL;	//头节点的后面没有节点 
}

//队列初始化
void initQueue(LinkQueue a[]){
	for(int i=0;i<10;i++){
		a[i].front=NULL;
		a[i].rear=NULL;
		a[i].len=0;
	} 
} 

//采用尾插法建立单链表
void tailInsert(LinkList &L){
	LinkNode *s;
	LinkNode *r=L;	//r是表尾指针 
	for(int i=0;i<n;i++){
		s=(LinkNode*)malloc(sizeof(LinkNode));
		s->data=a[i];
		r->next=s;
		r=s;	//r指向新的表尾节点 
	}
	r->next=NULL;
}

//输出
void out(LinkList L){
	LinkNode *p=L->next;
	while(p!=NULL){
		cout<<p->data<<" ";
		p=p->next;
	}
}

//除数 
int chushu(int n){
	int num=1;
	for(int i=1;i<n;i++){
		num*=10;
	}
	return num;
} 

//每个数据是1000以下的正整数,基数r=10
void sort(LinkList &L){
	LinkQueue a[10];
	LinkNode *p=L->next;	//p是当前处理的元素
	LinkNode *q;			//q是在收集数据时,指向链表L的尾部 
	int num;		//元素备份 
	int wei;		//元素位上的数
	initQueue(a);
	//总共进行三趟分配和收集
	//通过改变d的上限,可以实现更大数据的排序,d最大为10 
	//int的取值范围为: -2^31—2^31-1,即-2147483648—2147483647
	for(int d=1;d<=3;d++){
		p=L->next;
		while(p!=NULL){
			//i==1时,wei存储的是个位;i==2时,wei存储的是十位 
			wei=(p->data/chushu(d))%10;
			if(a[wei].len++==0){	//当前队列中没有元素 
				a[wei].front=p;
				a[wei].rear=p;
			}else{					//当前队列中起码有一个元素
				a[wei].rear->next=p;
				a[wei].rear=p;
			}
			p=p->next;
		}
		//清空链表,放入收集数据 
		L->next=NULL;
		q=L; 
		//收集元素到链表 
		for(int i=9;i>=0;i--){
			if(a[i].len!=0){
				cout<<d<<" "<<i<<endl;
				q->next=a[i].front;
				q=a[i].rear;
				a[i].front=NULL;
				a[i].rear=NULL;
				a[i].len=0;
			}
		}
		/*不加这一句话如果数据最后一个本身是1,则正常排序
		否则会陷入输出循环,目前还没想到原因 :(*/ 
		q->next=NULL;		
	}
} 

int main(){
	LinkList L;
	initLinkList(L);
	tailInsert(L);
	sort(L);
	out(L);
	return 0;
} 

说明:本文为个人学习理解总结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值