美文网首页
定义双链表,实现扑克三带二发牌排序

定义双链表,实现扑克三带二发牌排序

作者: vpractical | 来源:发表于2019-12-18 20:01 被阅读0次

[TOC]

结果展示

方块1; 黑桃1; 梅花3; 红桃4; 梅花4; 红桃5; 方块5; 梅花6; 方块7; 红桃8; 黑桃9; 梅花9; 红桃11; 梅花12; 红桃12; 梅花13; 红桃13;

梅花1; 红桃1; 梅花2; 黑桃4; 方块4; 黑桃5; 梅花5; 方块6; 红桃6; 梅花7; 黑桃8; 方块9; 红桃10; 方块10; 黑桃11; 梅花11; 方块11;

方块2; 红桃2; 黑桃2; 方块3; 黑桃3; 黑桃6; 黑桃7; 红桃7; 方块8; 梅花8; 红桃9; 黑桃10; 梅花10; 方块12; 黑桃12; 方块13; 黑桃13; 

双链表实现

理解

  • LinkedList就是双链表, 实现了List接口和Deque接口,Deque提供了双链表特性
  • ArrayList 内部维护数组保存元素,所以他是连续线性表,而链表是不连续内存的线性表
  • 双链表的每个元素是一个节点Node对象,每个节点保存前驱节点、后继节点的引用,单链表queue,每个节点保存后继节点的引用,例如MessageQueue
  • 双链表本身持有第一个节点first,最后一个节点last,以及size属性
  • 链表的插入操作,就是将插入元素装到一个新节点中,然后修改这个节点以及要插入位置前后两个节点的前驱后继引用,删除逆推
  • 链表的查找操作,循环查找的索引次数,每次拿到后继节点,循环完就是了,双链表可以从两头选择开始
  • 链式列表删除元素,时间复杂度O(1),而查找要从头或者尾开始,时间复杂度O(n)
  • !!!但是链式列表元素装在节点中,所以删除时是先找到节点O(n)+删除节点O(1)
  • 数组保存的元素,查找时用索引直接取,时间复杂度O(1),但是插入删除,需要将插入删除位置往后的元素都交换内存,时间复杂度O(n)
  • 这种链表队列是双向的,先进先出;继承List有个子类是Stack栈,只有一个入口先进后出

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList.但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList.因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。

实现

  • 1.根绝双链表的特性,先定义每个节点
    private static class Node<E> {
        E it;
        Node<E> prev;
        Node<E> next;

        public Node(Node<E> prev, E it, Node<E> next) {
            this.it = it;
            this.prev = prev;
            this.next = next;
        }
    }
  • 2.定义头节点、尾节点、size
    private int size;
    private Node<E> first;
    private Node<E> last;
  • 3.插入操作
    public void add(E it) {
        Node<E> node = new Node<>(last, it, null);
        if (last != null) {
            last.next = node;
        }
        last = node;
        if (first == null) {
            first = node;
        }
        size++;
    }
    
    public void add(int index,E it){
        //找到第index位置的节点,修改前驱后继引用
    }
    
  • 4.删除操作
    • 删除元素时,找到删除的节点,修改前驱后继的引用

扑克发牌实现

  • 定义Server类模拟服务端
  • Server要实现生成牌,洗牌,发牌
/**
 * 三带二服务器
 */
public class Server {
    //所有的牌
    private static List<Poker> list = new ArrayList<>();
    //3个牌手的牌
    private static LinkedList<LinkedList<Poker>> roles = new LinkedList<>();

    static {
        for (int i = 1; i <= 4; i++) {
            for (int j = 1; j <= 13; j++) {
                list.add(new Poker(i,j));
            }
        }

        for (int i = 0; i < 54; i++) {
            if(list.get(i).num == 3){
                list.remove(i);
                break;
            }
        }

        for (int i = 0; i < 4; i++) {
            roles.add(new LinkedList<Poker>());
        }
    }


    /**
     * 洗牌分牌
     */
    public static void init(){

        //随机取出发牌
        int index = 0;
        while (list.size() > 0){
            int random = (int) (Math.random() * list.size());
            Poker poker = list.remove(random);
            roles.get(index).add(poker);
            index++;
            if(index >= 3){
                index = 0;
            }
        }
    }

    /**
     * 牌手拿牌 :1  2  3
     * @param index
     */
    public static LinkedList<Poker> handOut(int index){
        return roles.get(index - 1);
    }
}

  • 定义扑克对象Poker,包含花色和大小属性
public class Poker {

    /**
     * type = 红桃,方块,黑桃,梅花 = 1.2.3.4
     * num = 1-13
     */
    public int type,num;

    public Poker(int type, int num){
        this.type = type;
        this.num = num;
    }

    @Override
    public String toString() {
        return name() + num + "; ";
    }

    public String name(){
        switch (type){
            case 1:
                return "红桃";
            case 2:
                return "方块";
            case 3:
                return "黑桃";
            case 4:
                return "梅花";
        }
        return "";
    }
}
  • 客户端先调用洗牌,再拿牌,排序
    Server.init();
    
    LinkedList<Poker> list =  Server.handOut(1);
    sort(list);
    System.out.println(list.toString());
    public static void sort(LinkedList<Poker> list){
        LinkedList<Poker>[] linkArr = new LinkedList[13];
        for (int i = 0; i < 13; i++) {
            linkArr[i] = new LinkedList<>();
        }

        for (int i = 0; i < list.size(); i++) {
            Poker poker = list.get(i);
            linkArr[poker.num - 1].add(poker);
        }

        list.clear();
        for (LinkedList l:linkArr) {
            list.addAll(l);
        }
    }

相关文章

  • 定义双链表,实现扑克三带二发牌排序

    [TOC] 结果展示 双链表实现 理解 LinkedList就是双链表, 实现了List接口和Deque接口,De...

  • 结构|链表

    学习笔记,可能有些谬误,请批判性阅读。 先给出链表的定义。 链表排序 归并排序用起来 删除链表倒数第n个节点 双指...

  • 23. 合并K个排序链表(Swift版)

    一、题目 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。示例: 二、解题 三、代码实现 D...

  • 扑克发牌

    两个下划线结尾(例如__getitem__)。比如obj[key]的背后就是__getitem__方法,为了求得m...

  • 二叉排序树

    1、二叉树的二叉链表结点结构定义 2、二叉排序树--查找 递归查找二叉排序树T中,是否存在key;指针f指向T的双...

  • 大体整理

    链表 给定两个链表和第三个链表,找规律然后进行算法实现。 二叉树 非递归实现二叉树中序遍历 数组 寻找两个排序数组...

  • 基于c++的扑克牌游戏

    1.课程设计的解答说明 创建一副扑克,并完成洗牌、发牌、显示、花色排序、面值排序、删除一张牌、删除一轮牌等操作。 ...

  • [源码和文档分享]基于c++的扑克牌游戏

    1.课程设计的解答说明 创建一副扑克,并完成洗牌、发牌、显示、花色排序、面值排序、删除一张牌、删除一轮牌等操作。 ...

  • 单链表 & 双链表& 单向循环链表的实现

    单链表 具体实现: 双链表 代码实现: 单向循环链表的实现 代码实现:

  • 链表

    单链表 C实现 Java实现 双链表 C实现 Java实现

网友评论

      本文标题:定义双链表,实现扑克三带二发牌排序

      本文链接:https://www.haomeiwen.com/subject/vmzunctx.html