从零开始学算法---线性表链式存储实现麻将排序

发布时间:2022-07-04 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了从零开始学算法---线性表链式存储实现麻将排序脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

先复习一些基本知识

链式存储的特点:用一组任意的存储单元(可以连续,也可以不连续)存储线性表的数据元素。

链式存储中每一个元素都是一个节点,每个节点中包含了数据域和指针域

相对数组存储来说,其优点是插入删除速度快,缺点是不支持随机访问,查询速度慢

什么是基数排序? 看看百度百科的定义:

基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其@R_566_1304@为O (nLOG(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。 通俗来说就是采用 “分配” 和 “收集”, 用对单关键码进行排序的方法,来实现对多关键码的排序

想要详细了解的可以看下这篇: 漫画:什么是基数排序?_程序员小灰的博客-CSDN博客

那么什么是链式基数排序呢?

所谓链式基数排序,就是实现基数排序时,因为有比较多的插入操作,应采用链表作存储结构

链式的基数排序算法解法思路(默认从小到大):1、以静态链表存储待排记录,并令表头指针指向第一个记录;2、“分配” 时,按当前“关键字位”所取值,将记录分配到不同的 “链队列” 中,每个队列中记录的 “关键字位” 相同;3、“收集”时,按当前关键字位取值从小到大将各队列首尾相链成一个链表;4、对每个关键字位均重复 2 和 3 两步。

从零开始学算法---线性表链式存储实现麻将排序

 

 

 来看今天的问题, 我们观察到,玩手机麻将的时候, 系统最初发给我们的牌是无序的, 像下面这样

从零开始学算法---线性表链式存储实现麻将排序

 

 

 这时候一般牌会翻过去一下,再翻回来的时候就已经做好排序了:

从零开始学算法---线性表链式存储实现麻将排序

 

 

 那么这是怎么实现的呢?

答案就是链式基数排序,思路如下:

第一次处理, 我们使用9个链表来收集1-9的点数, 遍历接收到的数据,把对应的点数放进对应的链表里

从零开始学算法---线性表链式存储实现麻将排序

 

 

 代码实现:

1, 创建麻将类, (原谅我蹩脚的英文)

 1 @H_406_74@public class MaJiang {
 2     
 3     int count;//点数 1-9
 4     int suIT;//花色, 万--1, 条--2, 筒--3
 5 
 6     public MaJiang(int count, int suit) {
 7         this.count = count;
 8         this.suit = suit;
 9     }
10 }

2, 第一次排序,这里我们先按点数排序, 也可以第一次按花色,第二次按点数

 1 public static void radixSort(LinkedList<;maJiang> list) {
 2         //定义一个长度为9的数组, 包含了9个链表,用来存放排序之后的数据
 3         LinkedList[] countLists =new LinkedList[9];
 4     
 5         //创建9个链表,放到数组中
 6         for (int i = 0; i < countLists.length; i++) {
 7             countLists[i] = new LinkedList<MaJiang>();
 8         }
 9         //遍历从服务器传回来的数据
10         while (list.size() > 0) {
11             //从list中取一个
12             //remove()方法会移除List中的第一个元素,并返回该元素
13             MaJiang temp = list.remove();
14             //根据该元素的点数,确定将其放在哪个链表中
15             countLists[temp.count-1].add(temp);
16         }
17         //while循环执行完后,list变成一个空List
18         //这时我们把完成第一轮排序后的数据依次加到list里,形成一个新的链表
19         for (int i = 0; i < countLists.length; i++) {
20             list.addAll(countLists[i]);
21         }
22     }
 1 public static void main(String[] args) {
 2         LinkedList<MaJiang> list = new LinkedList<MaJiang>();
 3         list.add(new MaJiang(7, 1));
 4         list.add(new MaJiang(9, 1));
 5         list.add(new MaJiang(9, 3));
 6         list.add(new MaJiang(6, 3));
 7         list.add(new MaJiang(9, 2));
 8         list.add(new MaJiang(1, 3));
 9         list.add(new MaJiang(4, 1));
10         list.add(new MaJiang(2, 1));
11         list.add(new MaJiang(1, 1));
12         list.add(new MaJiang(3, 1));
13         list.add(new MaJiang(9, 3));
14         list.add(new MaJiang(5, 3));
15         list.add(new MaJiang(6, 2));
16         list.add(new MaJiang(8, 2));
17         list.add(new MaJiang(9, 3));
18         
19         System.out.PRintln(list);
20         radixSort(list);
21         System.out.println(list);
22     }
23 
24 }

第一次排序执行完后,我们将得到点数从小到大以此排列的新链表

程序运行结果如下:(第一行为排序前,第二行为排序后)

从零开始学算法---线性表链式存储实现麻将排序

 

 接下来我们再对第一次排序得到的结果进行第二次排序

从零开始学算法---线性表链式存储实现麻将排序

 

 原理和第一次排序相同,建3个链表分别存储万条筒,然后把对应的花色放进去

 1 //接下来我们进行第二次排序
 2         LinkedList[] suitLists =new LinkedList[3];
 3         for (int i = 0; i < suitLists.length; i++) {
 4             suitLists[i] = new LinkedList<MaJiang>();
 5         }
 6         while (list.size() > 0) {
 7             //从list中取一个
 8             MaJiang temp = list.remove();
 9             //根据该元素的点数,确定将其放在哪个链表中
10             suitLists[temp.suit-1].add(temp);
11         }
12         for (int i = 0; i < suitLists.length; i++) {
13             list.addAll(suitLists[i]);
14         }

代码逻辑和第一次排序类似, 看下最终运行结果

从零开始学算法---线性表链式存储实现麻将排序

 

 

链式基数排序适用于数据量在二三十个左右的排序

 

脚本宝典总结

以上是脚本宝典为你收集整理的从零开始学算法---线性表链式存储实现麻将排序全部内容,希望文章能够帮你解决从零开始学算法---线性表链式存储实现麻将排序所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。