_DataStructure_C_Impl:基数排序

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define MaxNumKey 6 /*关键字项数的最大值*/
#define Radix 10	/*关键字基数,此时是十进制整数的基数*/
#define MaxSize 1000
#define N 6
typedef int KeyType; /*定义关键字类型*/
typedef struct
{
	KeyType key[MaxNumKey]; /*关键字*/
	int next;
}SListCell;	/*静态链表的结点类型*/

typedef struct
{
	SListCell data[MaxSize];		/*存储元素,data[0]为头结点*/
	int keynum;						/*每个元素的当前关键字个数*/
	int length;						/*静态链表的当前长度*/
}SList;		/*静态链表类型*/
typedef int addr[Radix]; /*指针数组类型*/

typedef struct
{
	KeyType key; /* 关键字项 */
}DataType;

void PrintList(SList L);
void PrintList2(SList L);
void InitList(SList *L,DataType d[],int n);
int trans(char c);
void Distribute(SListCell data[],int i,addr f,addr r);
void Collect(SListCell data[],addr f,addr r);
void RadixSort(SList *L);
void InitList(SList *L,DataType a[],int n)
	/* 初始化静态链表L(把数组D中的数据存于L中) */
{
	char ch[MaxNumKey],ch2[MaxNumKey];
	int i,j,max=a[0].key;
	for(i=1;i<n;i++)					/*将最大的关键字存入max*/
		if(max<a[i].key)
			max=a[i].key;
	(*L).keynum=(int)(log10((float)max))+1;	/*求关键字的个数*/
	(*L).length=n;						/*待排序个数*/
	for(i=1;i<=n;i++)
	{
		itoa(a[i-1].key,ch,10);					/*将整型转化为字符,并存入ch*/
		for(j=strlen(ch);j<(*L).keynum;j++)		/*如果ch的长度<max的位数,则在ch前补'0'*/
		{
			strcpy(ch2,"0");
			strcat(ch2,ch);
			strcpy(ch,ch2);
		}
		for(j=0;j<(*L).keynum;j++)				/*将每个关键字的各个位数存入key*/
			(*L).data[i].key[j]=ch[(*L).keynum-1-j];
	}
	for(i=0;i<(*L).length;++i)				/*初始化静态链表*/
		(*L).data[i].next=i+1;
	(*L).data[(*L).length].next=0;
}

int trans(char c)
	/*将字符c转化为对应的整数*/
{
	return c-'0';
}
void Distribute(SListCell data[],int i,addr f,addr r)
	/*为data中的第i个关键字key[i]建立Radix个子表,使同一子表中元素的key[i]相同*/
	/*f[0..Radix-1]和r[0..Radix-1]分别指向各个子表中第一个和最后一个元素*/
{
	int j,p;
	for(j=0;j<Radix;j++)				/*将各个子表初始化为空表*/
		f[j]=0;
	for(p=data[0].next;p;p=data[p].next)
	{
		j=trans(data[p].key[i]);		/*将对应的关键字字符转化为整数类型*/
		if(!f[j])						/*f[j]是空表,则f[j]指示第一个元素*/
			f[j]=p;
		else
			data[r[j]].next=p;
		r[j]=p;							/*将p所指的结点插入第j个子表中*/
	}
}

void Collect(SListCell data[],addr f,addr r)
	/*按key[i]将f[0..Radix-1]所指各子表依次链接成一个静态链表*/
{
	int j,t;
	for(j=0;!f[j];j++);	/*找第一个非空子表,succ为求后继函数*/
	data[0].next=f[j];
	t=r[j];				/*r[0].next指向第一个非空子表中第一个结点*/
	while(j<Radix-1)
	{
		for(j=j+1;j<Radix-1&&!f[j];j++);	/*找下一个非空子表*/
		if(f[j])							/*将非空链表连接在一起*/
		{
			data[t].next=f[j];
			t=r[j];
		}
	}
	data[t].next=0;		/*t指向最后一个非空子表中的最后一个结点*/
}

void RadixSort(SList *L)
	/*对L进行基数排序,使得L成为按关键字非递减的静态链表,L.r[0]为头结点*/
{
	int i;
	addr f,r;
	for(i=0;i<(*L).keynum;i++)			/*由低位到高位依次对各关键字进行分配和收集*/
	{
		Distribute((*L).data,i,f,r);	/*第i趟分配*/
		Collect((*L).data,f,r);			/*第i趟收集*/
		printf("第%d趟收集后:",i+1);
		PrintList2(*L);
	}
}

void main()
{
	DataType d[N]={268,126,63,730,587,184};
	SList L;
	InitList(&L,d,N);
	printf("待排序元素个数是%d个,关键字个数为%d个\n",L.length,L.keynum);
	printf("排序前的元素:\n");
	PrintList2(L);
	printf("排序前的元素的存放位置:\n");
	PrintList(L);
	RadixSort(&L);
	printf("排序后元素的存放位置:\n");
	PrintList(L);
	system("pause");
}
void PrintList(SList L)
	/*按数组序号形式输出静态链表*/
{
	int i,j;
	printf("序号 关键字 地址\n");
	for(i=1;i<=L.length;i++)
	{
		printf("%2d    ",i);
		for(j=L.keynum-1;j>=0;j--)
			printf("%c",L.data[i].key[j]);
		printf("    %d\n",L.data[i].next);
	}
}
void PrintList2(SList L)
	/*按链表形式输出静态链表*/
{
	int i=L.data[0].next,j;
	while(i)
	{
		for(j=L.keynum-1;j>=0;j--)
			printf("%c",L.data[i].key[j]);
		printf(" ");
		i=L.data[i].next;
	}
	printf("\n");
}

版权声明:本文为博主原创文章,未经博主允许不得转载|Copyright ©2011-2015,Supernatural, All Rights Reserved.

时间: 2024-10-19 02:55:11

_DataStructure_C_Impl:基数排序的相关文章

基数排序及C语言实现

基数排序的基本思想是对数字的每一位进行排序,先对个位排序,然后十位,百位--,对每一位进行排序时,要求采用稳定排序算法,比如前面讨论过的计数排序.以一个三位整数为例,过程是这样的: 该算法同样能达到线性复杂度.下面是代码.(好吧,我知道写的很菜--) #include <stdio.h> #define NUM 10 //数组元素个数 void counting_sort(int a[],int b[],int c[],int atemp[]); int main() { int i; int

数据结构-基数排序

#include <iostream> using namespace std; void CountSort(int* a,int k,int n){ int s = 1; for(int i=0;i<k;i++){ s *= 10; } int* b = new int[n]; int* c = new int[n]; for(int i=0;i<n;i++){ b[i] = 0; c[i] = 0; } int tmp1 = 0; for(int i=0;i<n;i++

基本排序算法(冒泡排序 选择排序 插入排序 快速排序 归并排序 基数排序 希尔排序)

冒泡排序 public static void bubbleSort(int[] arr){ int lgn = arr.length; for (int i = 0; i < lgn - 1; i++) { for (int j = 0; j < lgn - 1 - i; j++) { if(arr[j] > arr[j + 1]){ int temp = arr[j + 1]; arr[j + 1] = arr[j]; arr[j] = temp; } } } } 选择排序 publ

基数排序与桶排序,计数排序【详解】

桶排序简单入门篇^-^ 在我们生活的这个世界中到处都是被排序过的东东.站队的时候会按照身高排序,考试的名次需要按照分数排序,网上购物的时候会按照价格排序,电子邮箱中的邮件按照时间排序……总之很多东东都需要排序,可以说排序是无处不在.现在我们举个具体的例子来介绍一下排序算法. 首先出场的是我们的主人公小哼,上面这个可爱的娃就是啦.期末考试完了老师要将同学们的分数按照从高到低排序.小哼的班上只有5个同学,这5个同学分别考了5分.3分.5分.2分和8分,哎,考得真是惨不忍睹(满分是10分).接下来将分

基数排序(桶排序) 不同方法

详细解释:算法导论/数据结构书 1.链式基数排序 //n个数,每个数有g个关键字//排序:从最后的关键字开始到最前的关键字//分配+收集//每个关键字分配+收集需要n+n时间,而共有g个关键字,时间复杂度为O(2ng),效率很高.//如果用数组,数据集中在一个区间,则区间的长度很长,另外的区间的内存浪费了.//用链表可以解决这个问题,且数据不需要先后顺序,所以无必要非要用数组 1 #include <stdio.h> 2 #include <stdlib.h> 3 //个数 4 #

基数排序

基本解法 第一步 以LSD为例,假设原来有一串数值如下所示: 73, 22, 93, 43, 55, 14, 28, 65, 39, 81 首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中: 0 1 81 2 22 3 73 93 43 4 14 5 55 65 6 7 8 28 9 39 第二步 接下来将这些桶子中的数值重新串接起来,成为以下的数列: 81, 22, 73, 93, 43, 14, 55, 65, 28, 39 接着再进行一次分配,这次是根据十位数来分配: 0

重复造轮子系列--计数,基数排序

计数,基数的中文读音都一样,这翻译的人还嫌我们计算机不够乱,真的想吐槽. 不管了,毕竟代码还是不一样的. 1.计数排序(counter sort): 通过一个上限来统计集合里的数值(或者其他非数值类型映射的数值),并累计比小于自己(包括)的数值的统计的个数,从而形成排序的索引(也就是前面有多少个小于我的,我的位置就确定了). 普通计数排序代码:(仍需优化,valuetype默认是整数类型) 1 template<typename _InIt> 2 void counter_sort(_InIt

基数排序LSD_Radix_Sort

裸基数排序 #include <iostream> using namespace std; struct list_ { int v; int next; }a[1005]; void print(list_ a[],int head) { for (int i = head; i != -1; i = a[i].next) { cout << a[i].v <<" "; } cout << endl; } int LSD_radix_

排序算法----基数排序(RadixSort(L))单链表智能版本

转载http://blog.csdn.net/Shayabean_/article/details/44885917博客 先说说基数排序的思想: 基数排序是非比较型的排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较. 将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零.然后,从最低位开始,依次进行一次排序.在每一次排序中,按照当前位把数组元素放到对应 的桶当中,然后把桶0到桶9中的元素按先进先出的方式放回数组中.这样从最低位排序一直到最高位排序完成以后,