桶排序升级之基数排序c语言实现10.1.2
来源:互联网 发布:中央电大网络教育专业 编辑:程序博客网 时间:2024/05/17 22:20
上一篇介绍了不稳定的快速排序,这回介绍基数排序
基数排序是基于分配策略的排序,不是一种比较排序,不受到 O(n log n) 下限的影响,是一种稳定的排序算法,并且它可以应用于多关键字排序。
次位优先基数排序
先按照优先级别最低的位对序列进行排序,下一步按照稍高优先级的位对序列进行排序,直到最高位时候整个序列就是有序序列
主位优先基数排序
先按照优先级最高的位对序列进行排序,对序列中此位相同的元素按照稍低优先级位进行再排序(局部调整),最后得到的整个序列就是有序序列
说那么多不如直接分析代码来的实在
/* 基数排序 - 次位优先 */ /* 假设元素最多有MaxDigit个关键字,基数全是同样的Radix */ #define MaxDigit 4 #define Radix 10 /* 桶元素结点 */ typedef struct Node *PtrToNode; struct Node { int key; PtrToNode next; }; /* 桶头结点 */ struct HeadNode { PtrToNode head, tail; }; typedef struct HeadNode Bucket[Radix]; int GetDigit ( int X, int D ) { /* 默认次位D=1, 主位D<=MaxDigit */ int d, i; for (i=1; i<=D; i++) { d = X % Radix; X /= Radix; } return d; } void LSDRadixSort( ElementType A[], int N ) { /* 基数排序 - 次位优先 */ int D, Di, i; Bucket B; PtrToNode tmp, p, List = NULL; for (i=0; i<Radix; i++) /* 初始化每个桶为空链表 */ B[i].head = B[i].tail = NULL; for (i=N-1; i>=0; i--) { /* 将原始序列按头插法存入初始链表List */ tmp = (PtrToNode)malloc(sizeof(struct Node)); tmp->key = A[i]; tmp->next = List; List = tmp; } /* 下面开始排序 */ for (D=1; D<=MaxDigit; D++) { /* 对数据的每一位循环处理 */ /* 下面是分配的过程 */ p = List; while (p) { Di = GetDigit(p->key, D); /* 获得当前元素的当前位数字 */ /* 从List中摘除 */ tmp = p; p = p->next; /* 插入B[Di]号桶尾 */ tmp->next = NULL; if (B[Di].head == NULL) B[Di].head = B[Di].tail = tmp; else { B[Di].tail->next = tmp; B[Di].tail = tmp; } } /* 下面是收集的过程 */ List = NULL; for (Di=Radix-1; Di>=0; Di--) { /* 将每个桶的元素顺序收集入List */ if (B[Di].head) { /* 如果桶不为空 */ /* 整桶插入List表头 */ B[Di].tail->next = List; List = B[Di].head; B[Di].head = B[Di].tail = NULL; /* 清空桶 */ } } } /* 将List倒入A[]并释放空间 */ for (i=0; i<N; i++) { tmp = List; List = List->next; A[i] = tmp->key; free(tmp); } }
/* 基数排序 - 主位优先 */ /* 假设元素最多有MaxDigit个关键字,基数全是同样的Radix */ #define MaxDigit 4 #define Radix 10 /* 桶元素结点 */ typedef struct Node *PtrToNode; struct Node{ int key; PtrToNode next; }; /* 桶头结点 */ struct HeadNode { PtrToNode head, tail; }; typedef struct HeadNode Bucket[Radix]; int GetDigit ( int X, int D ) { /* 默认次位D=1, 主位D<=MaxDigit */ int d, i; for (i=1; i<=D; i++) { d = X%Radix; X /= Radix; } return d; } void MSD( ElementType A[], int L, int R, int D ) { /* 核心递归函数: 对A[L]...A[R]的第D位数进行排序 */ int Di, i, j; Bucket B; PtrToNode tmp, p, List = NULL; if (D==0) return; /* 递归终止条件 */ for (i=0; i<Radix; i++) /* 初始化每个桶为空链表 */ B[i].head = B[i].tail = NULL; for (i=L; i<=R; i++) { /* 将原始序列头插法存入初始链表List */ tmp = (PtrToNode)malloc(sizeof(struct Node)); tmp->key = A[i]; tmp->next = List; List = tmp; } /* 下面是分配的过程 */ p = List; while (p) { Di = GetDigit(p->key, D); /* 获得当前元素的当前位数字 */ /* 从List中摘除 */ tmp = p; p = p->next; /* 插入B[Di]号桶 */ if (B[Di].head == NULL) B[Di].tail = tmp; tmp->next = B[Di].head; B[Di].head = tmp; } /* 下面是收集的过程 */ i = j = L; /* i, j记录当前要处理的A[]的左右端下标 */ for (Di=0; Di<Radix; Di++) { /* 对于每个桶 */ if (B[Di].head) { /* 将非空的桶整桶倒入A[], 递归排序 */ p = B[Di].head; while (p) { tmp = p; p = p->next; A[j++] = tmp->key; free(tmp); } /* 递归对该桶数据排序, 位数减1 */ MSD(A, i, j-1, D-1); i = j; /* 为下一个桶对应的A[]左端 */ } } } void MSDRadixSort( ElementType A[], int N ) { /* 统一接口 */ MSD(A, 0, N-1, MaxDigit); }
时间效率[1] :设待排序列为n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集。 空间效率:需要2*radix个指向队列的辅助空间,以及用于静态链表的n个指针。
0 0
- 桶排序升级之基数排序c语言实现10.1.2
- 基数排序C语言实现
- 基数排序-C语言实现
- 基数排序 C语言实现
- 基数排序-C语言实现
- 基数排序与桶排序C实现
- 基数排序的C语言实现
- 基数排序及C语言实现
- 基数排序单链表实现(C语言)
- 基数排序C语言代码实现
- 排序算法c语言描述---基数排序
- 排序算法C++&&Python实现---基数排序
- 基数排序(基于C语言的实现)
- 排序【2】之希尔排序的C语言实现
- Java实现-高效排序算法之基数排序
- python实现计数排序、桶排序、基数排序
- 排序算法之基数排序/桶排序
- 分配排序之--桶排序,基数排序
- stm32Jlink仿真和调试笔记
- 【数论】洛谷 P1147 连续自然数和
- 【厚积薄发】编程技术总结8—常见笔试面试题小结
- SpringBoot实战 之 数据库
- 1464: 最低等级
- 桶排序升级之基数排序c语言实现10.1.2
- 图像坐标系转世界坐标系的方法
- 在构建maven项目中 <version>${spring.version}</version>含义
- CentOS7使用firewalld打开关闭防火墙与端口
- 【搜索】洛谷 P1141 01迷宫
- 数据结构复习5.Comparable和Comparator
- 浅谈Java中的equals()和==
- 在Android Studio中有六种依赖
- 【深度学习】---行人检测应用二