链式基数排序
2014-06-02 02:09
369 查看
/* c1.h (程序名) */ #include<string.h> #include<ctype.h> #include<malloc.h> /* malloc()等 */ #include<limits.h> /* INT_MAX等 */ #include<stdio.h> /* EOF(=^Z或F6),NULL */ #include<stdlib.h> /* atoi() */ #include<io.h> /* eof() */ #include<math.h> /* floor(),ceil(),abs() */ #include<process.h> /* exit() */ /* 函数结果状态代码 */ #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 /* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 */ typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */ typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */ typedef int ElemType; /* alg10-11.c 链式基数排序 */ typedef int InfoType; /* 定义其它数据项的类型 */ typedef int KeyType; /* 定义RedType类型的关键字为整型 */ typedef struct { KeyType key; /* 关键字项 */ InfoType otherinfo; /* 其它数据项 */ }RedType; /* 记录类型(同c10-1.h) */ typedef char KeysType; /* 定义关键字类型为字符型 */ #define MAX_NUM_OF_KEY 8 /* 关键字项数的最大值 */ #define RADIX 10 /* 关键字基数,此时是十进制整数的基数 */ #define MAX_SPACE 1000 typedef struct { KeysType keys[MAX_NUM_OF_KEY]; /* 关键字 */ InfoType otheritems; /* 其它数据项 */ int next; }SLCell; /* 静态链表的结点类型 */ typedef struct { SLCell r[MAX_SPACE]; /* 静态链表的可利用空间,r[0]为头结点 */ int keynum; /* 记录的当前关键字个数 */ int recnum; /* 静态链表的当前长度 */ }SLList; /* 静态链表类型 */ typedef int ArrType[RADIX]; /* 指针数组类型 */
#include "linkRadix.h" void InitList(SLList *L, RedType D[], int n) { /* 初始化静态链表L(把数组D中的数据存于L中) */ char c[MAX_NUM_OF_KEY], c1[MAX_NUM_OF_KEY]; int i, j, max = D[0].key; /* max为关键字的最大值 */ for (i = 1; i<n; i++) if (max<D[i].key) max = D[i].key; (*L).keynum = (int)(ceil(log10((double)max))); (*L).recnum = n; for (i = 1; i <= n; i++) { (*L).r[i].otheritems = D[i - 1].otherinfo; _itoa(D[i - 1].key, c, 10); /* 将10进制整型转化为字符型,存入c */ for (j = strlen(c); j<(*L).keynum; j++) /* 若c的长度<max的位数,在c前补'0' */ { strcpy(c1, "0"); strcat(c1, c); strcpy(c, c1); } for (j = 0; j<(*L).keynum; j++) (*L).r[i].keys[j] = c[(*L).keynum - 1 - j]; } } int ord(char c) { /* 返回k的映射(个位整数) */ return c - '0'; } void Distribute(SLCell r[], int i, ArrType f, ArrType e) /* 算法10.15 */ { /* 静态键表L的r域中记录已按(keys[0],...,keys[i-1])有序。本算法按 */ /* 第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同。 */ /* f[0..RADIX-1]和e[0..RADIX-1]分别指向各子表中第一个和最后一个记录 */ int j, p; for (j = 0; j<RADIX; ++j) f[j] = 0; /* 各子表初始化为空表 */ for (p = r[0].next; p; p = r[p].next) { j = ord(r[p].keys[i]); /* ord将记录中第i个关键字映射到[0..RADIX-1] */ if (!f[j]) f[j] = p; else r[e[j]].next = p; e[j] = p; /* 将p所指的结点插入第j个子表中 */ } } int succ(int i) { /* 求后继函数 */ return ++i; } void Collect(SLCell r[], ArrType f, ArrType e) { /* 本算法按keys[i]自小至大地将f[0..RADIX-1]所指各子表依次链接成 */ /* 一个链表,e[0..RADIX-1]为各子表的尾指针。算法10.16 */ int j, t; for (j = 0; !f[j]; j = succ(j)); /* 找第一个非空子表,succ为求后继函数 */ r[0].next = f[j]; t = e[j]; /* r[0].next指向第一个非空子表中第一个结点 */ while (j<RADIX - 1) { for (j = succ(j); j<RADIX - 1 && !f[j]; j = succ(j)); /* 找下一个非空子表 */ if (f[j]) { /* 链接两个非空子表 */ r[t].next = f[j]; t = e[j]; } } r[t].next = 0; /* t指向最后一个非空子表中的最后一个结点 */ } void printl(SLList L) { /* 按链表输出静态链表 */ int i = L.r[0].next, j; while (i) { for (j = L.keynum - 1; j >= 0; j--) printf("%c", L.r[i].keys[j]); printf(" "); i = L.r[i].next; } } void RadixSort(SLList *L) { /* L是采用静态链表表示的顺序表。对L作基数排序,使得L成为按关键字 */ /* 自小到大的有序静态链表,L.r[0]为头结点。算法10.17 */ int i; ArrType f, e; for (i = 0; i<(*L).recnum; ++i) (*L).r[i].next = i + 1; (*L).r[(*L).recnum].next = 0; /* 将L改造为静态链表 */ for (i = 0; i<(*L).keynum; ++i) { /* 按最低位优先依次对各关键字进行分配和收集 */ Distribute((*L).r, i, f, e); /* 第i趟分配 */ Collect((*L).r, f, e); /* 第i趟收集 */ printf("第%d趟收集后:\n", i + 1); printl(*L); printf("\n"); } } void print(SLList L) { /* 按数组序号输出静态链表 */ int i, j; printf("keynum=%d recnum=%d\n", L.keynum, L.recnum); for (i = 1; i <= L.recnum; i++) { printf("keys="); for (j = L.keynum - 1; j >= 0; j--) printf("%c", L.r[i].keys[j]); printf(" otheritems=%d next=%d\n", L.r[i].otheritems, L.r[i].next); } } void Sort(SLList L, int adr[]) /* 改此句(类型) */ { /* 求得adr[1..L.length],adr[i]为静态链表L的第i个最小记录的序号 */ int i = 1, p = L.r[0].next; while (p) { adr[i++] = p; p = L.r[p].next; } } void Rearrange(SLList *L, int adr[]) /* 改此句(类型) */ { /* adr给出静态链表L的有序次序,即L.r[adr[i]]是第i小的记录。 */ /* 本算法按adr重排L.r,使其有序。算法10.18(L的类型有变) */ int i, j, k; for (i = 1; i<(*L).recnum; ++i) /* 改此句(类型) */ if (adr[i] != i) { j = i; (*L).r[0] = (*L).r[i]; /* 暂存记录(*L).r[i] */ while (adr[j] != i) { /* 调整(*L).r[adr[j]]的记录到位直到adr[j]=i为止 */ k = adr[j]; (*L).r[j] = (*L).r[k]; adr[j] = j; j = k; /* 记录按序到位 */ } (*L).r[j] = (*L).r[0]; adr[j] = j; } } #define N 10 void main() { RedType d = { { 278, 1 }, { 109, 2 }, { 63, 3 }, { 930, 4 }, { 589, 5 }, { 184, 6 }, { 505, 7 }, { 269, 8 }, { 8, 9 }, { 83, 10 } }; SLList l; int *adr; InitList(&l, d, N); printf("排序前(next域还没赋值):\n"); print(l); RadixSort(&l); printf("排序后(静态链表):\n"); print(l); adr = (int*)malloc((l.recnum)*sizeof(int)); Sort(l, adr); Rearrange(&l, adr); printf("排序后(重排记录):\n"); print(l); }
相关文章推荐
- 数据结构——链式基数排序
- 数据结构——链式基数排序
- 链式队列实现基数排序
- 排序-链式基数排序
- 链式基数排序
- C++代码,数据结构-内部排序-基数排序-链式基数排序
- LSD:低关键字优先;链式基数排序;lst.remove();取出和删除表头元素
- 链式基数排序
- 【数据结构】算法10.15-10.17 链式基数排序
- 基数排序与链式基数排序
- C语言中数据结构之链式基数排序
- LSD链式基数对数值排序BUG;列出串中有顺序的三个字符
- 基数排序--链式基数排序(Radix)
- 数据结构_内部排序_链式基数排序
- 【Data_Structure笔记7】排序算法之【链式基数排序】
- 基数排序
- Java排序算法以及算法改进总结(计数排序、基数排序、桶排序)
- 基数排序的完整实现
- 基数排序-数组模拟实现
- 基数排序