数据结构与算法分析 C 语言描述第二版第三章——链表实现基数排序

数据结构与算法分析 C 语言描述第二版第三章——链表实现基数排序

基数排序(radix sort)算法

算法思想见:
基数排序
排序算法----基数排序(RadixSort(L,max))单链表版本
基数排序从低位而不是从高位排序的原因:
why radix sort preferred to Least Significant Digit first

程序

程序从小到大排序

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define RADIX 10 //基数
#define POS_LEN 3 //输入数字的最大位数
struct node;
typedef struct node *ptrtonode;
typedef ptrtonode list;
typedef ptrtonode position;
struct node {
	int data;
	ptrtonode next;
};
list InitList(void);
void CreatList(list L);
void ShowList(list L);
void RadixSort(list L);
void DeleteList(list L);
int main(void)
{
	list L;
	L = InitList();
	CreatList(L);
	puts("\nOriginal numbers:");
	ShowList(L);
	puts("\nSorted numbers:");
	RadixSort(L);
	ShowList(L);
	DeleteList(L);
	return 0;
}
list InitList(void)
{
	list L = (list)malloc(sizeof(struct node));
	if (L == NULL) {
		fprintf(stderr,"out of space\n");
		exit(EXIT_FAILURE);
	}
	L->next = NULL;
	return L;
}
void InsertTail(int n, position p) {
	list tem = (list)malloc(sizeof(struct node));
	tem->data = n;
	tem->next = p->next;
	p->next = tem;
}
void eatline(void) {
	while (getchar() != '\n')
		continue;
}
void CreatList(list L)
{
	printf("Please enter numbers (no more than %d digits):\n",POS_LEN);
	position p = L;
	int n;
	while (scanf("%d",&n) == 1) {
		if ((int)(n / (int)pow(10, POS_LEN)) == 0) {
			InsertTail(n,p);
			p = p->next;
		}
		else
			break;
	}
	eatline();
}
void ShowList(list L) {
	position p = L->next;
	while (p) {
		printf("%d ",p->data);
		p = p->next;
	}
	putchar('\n');
}
int IsEmpty(list L)
{
	return L->next == NULL;
}
int IsLast(position p, list L)
{
	return p->next == NULL;
}
//将L2的首节点,即头节点后一个节点移到L1的尾节点后面
void MoveNode(list L1, list L2) {
	position tem1 = L1, tem2;
	if (IsEmpty(L2)) {
		fprintf(stderr,"Empty linked list\n");
		exit(EXIT_FAILURE);
	}
	while (!IsLast(tem1,L1)) 
		tem1 = tem1->next;
	//tem2指向L2所在链表的首节点
	//再将该节点从链表中移除
	tem2 = L2->next;
	L2->next = tem2->next;
	//tem2指向的节点放到L1所在链表尾节点后面
	tem1->next = tem2;
	tem2->next = NULL;
}
void RadixSort(list L) {
	if (IsEmpty(L)) {
		fprintf(stderr,"Empty linked list\n");
		exit(EXIT_FAILURE);
	}
	list bucket[RADIX];
	int num, nsub;
	for (int i = 0; i < RADIX; i++)//建立桶并初始化
		bucket[i] = InitList();
	/*从低位开始将链表中的节点移到对应的桶中
	第一次循环:i=0,按照最低位分配链表中数值,下标nsub = num%10
	一次分配按照最低位将链表中元素全部取出后,
	再按照桶下标顺序将元素按顺序再全部放回链表中
	接着开始第二次循环,此时 i=1,按照十位分配链表值,nsub=num/10%10
	按此规律循环,直到按照最高位排序好,再按顺序取出即排序完成
	*/
	for (int i = 0; i < POS_LEN; i++) {
		while (!IsEmpty(L)) { 
			num = L->next->data;
			nsub = (int)(num / pow(10,i)) % 10;
			MoveNode(bucket[nsub], L);
		}
		for (int j = 0; j < RADIX; j++) 
			while (!IsEmpty(bucket[j]))
				MoveNode(L, bucket[j]);
	}
	//排序完成将桶释放
	for (int i = 0; i < RADIX; i++)
		free(bucket[i]);
}
void DeleteList(list L)
{
	position p = L->next, tem;
	L->next = NULL;
	while (p) {
		tem = p->next;
		free(p);
		p = tem;
	}
}

测试结果:

Please enter numbers (no more than 3 digits):
64 8 216 512 27 729 0 1 343 125 1234 2 1

Original numbers:
64 8 216 512 27 729 0 1 343 125 

Sorted numbers:
0 1 8 27 64 125 216 343 512 729 
发布了120 篇原创文章 · 获赞 2 · 访问量 5796

猜你喜欢

转载自blog.csdn.net/Lee567/article/details/103619262
今日推荐