首页 > 其他分享 >【数据结构】:链表实现洗牌功能

【数据结构】:链表实现洗牌功能

时间:2024-07-22 17:28:57浏览次数:16  
标签:cardList int 洗牌 List 链表 new 数据结构 public Card

在这里插入图片描述

在这里插入图片描述
此操作包含的基本功能有:

  1. 组牌:组建 52 张扑克牌
  • 四种花色:“♥️”,“♠️”,“⬛️”,“♣️”
  • 每种花色 13 张牌:1~13
  1. 洗牌:将 52 张扑克牌打乱顺序
  2. 发牌:给三个人每人发 5 张牌

扩展功能:

  • 清牌:将每人手中牌按照面值进行从大到小排序

Card 类

在此类中,我们将完成对每一张牌的构造

  • 类中含有成员变量

    • 花色:suit
    • 面值:rank
  • 带有一个含参的构造方法,用来之后传入对应参数进行新牌的构造

  • 重写 toString() 方法,让输出的结果更美观


public class Card {
    public int rank;
    public String suit;

    public Card(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }


    @Override
    public String toString() {
        return "{" +
                 + rank +
                " " + suit +
                "}";
    }
}


CardBox 类

所有的功能都将在这个类中进行具体地实现


组牌

组建 52 张牌:List<Card> buildCard()

  1. 创建一个容量为 52,接收对象为 Card 的链表 cardList
  2. 两个 for 循环,为 Card 类里面的两个成员变量造值
  3. 随后依次为 Card 类实例化对象,将两个成员变量传入 Card 的构造方法中,创造出一张牌
  4. 最后依次将实例化出来的对象加入链表

public class CardBox {
    public static final String[] suits = {"♥️", "♠️", "⬛️", "♣️"};

    public static List<Card> makeCard() {
        List<Card> cardList = new ArrayList<>(52);
        for (int i = 0; i < 4; i++) {
            for (int j = 1; j <= 13; j++) {
                int rank = j;
                String suit = suits[i];
                Card card = new Card(rank, suit);
                cardList.add(card);
            }
        }
        return cardList;
    }
}


洗牌

运用下标交换进行牌的打乱:void shuffle(List<Card> cardList)

  1. 使用随机数函数 Random 进行下标交换匹配,用随机数函数创造一个范围内的下标 randomIndex
  2. 再让随机数 randomIndex 下标在顺序表中对应的牌与目标牌进行交换
  3. 交换需要用到一个自定义函数:void swap(List<Card> cardList, int i, int j)
    • 此函数对 cardList 链表进行操作,将其中 i 位置的数据与 j 位置的数据进行交换

 public static void shuffle(List<Card> cardList) {
    for (int i = cardList.size() - 1; i > 0; i--) {
        int randomIndex = new Random().nextInt(i);
        swap(cardList,randomIndex,i);
    }
}

private static void swap(List<Card> cardList, int i, int j){
    Card tmp = cardList.get(i);
    cardList.set(i,cardList.get(j));
    cardList.set(j,tmp);
}


发牌

将牌分发给三个人:void drawCard (List<Card> cardList)

  1. 为四个人创建三个 Card 类型的链表,就相当于是“他们的手”,用来拿他们发到的牌
  2. 再创建一个以“他们的手”为类型的链表,就相当于是“发牌人的手”,用来将发好的牌堆发给他们
  3. 发牌的原理是依次移走下标为 0 的那张牌

public void drawCard (List<Card> cardList) {
    List<Card> hand1 = new ArrayList<>();
    List<Card> hand2 = new ArrayList<>();
    List<Card> hand3 = new ArrayList<>();

    List<List<Card>> hands = new ArrayList<>();
    hands.add(hand1);
    hands.add(hand2);
    hands.add(hand3);

    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 3; j++) {
            hands.get(j).add(cardList.remove(0));
        }
    }
}


扩展:清牌

在发牌之后,将每人手中牌按照面值进行从大到小排序:

  1. 重写 Collection 接口中的 sort() 方法
  2. 在参数中直接传入一个用来排序链表的比较器

public void drawCard (List<Card> cardList){
    List<Card> hand1 = new ArrayList<>();
    List<Card> hand2 = new ArrayList<>();
    List<Card> hand3 = new ArrayList<>();

    List<List<Card>> hands = new ArrayList<>();
    hands.add(hand1);
    hands.add(hand2);
    hands.add(hand3);

    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 3; j++) {
            hands.get(j).add(cardList.remove(0));
        }
    }
    for (int i = 0; i < 3; i++) {
        Collections.sort(hands.get(i), new Comparator<Card>() {
            @Override
            public int compare(Card o1, Card o2) {
                return o1.rank - o2.rank;
            }
        });

    }

    System.out.println("第一个人的牌"+hand1);
    System.out.println("第二个人的牌"+hand2);
    System.out.println("第三个人的牌"+hand3);
}


运行结果

在这里插入图片描述

标签:cardList,int,洗牌,List,链表,new,数据结构,public,Card
From: https://blog.csdn.net/Yechiel/article/details/140612482

相关文章

  • 数据结构与算法总结——线性表
    目录2线性表2.1线性表的定义2.2线性表的基本操作2.2顺序表2.2.1顺序表的定义2.2.2顺序表的基本操作2.3链式表2.3.1链表的定义2.3.2链表的分类2.3.3单向链表2.3.3.1结点设计2.3.3.2链表的初始化2.3.3.3数据的插入2.3.3.4数据的删除2.3.3.5销毁链......
  • 手撕数据结构01--单链表(附源码)
    目录1.链表的概念和结构1.1链表的概念1.2单链表结构2.实现单链表2.1节点定义2.2链表功能2.3 创建节点2.4尾插2.5头插2.6打印2.7尾删2.8头删2.9查找2.10指定位置插入2.11指定位置之后插入2.12删除pos节点2.13删除pos之后的节点2.14销毁链表......
  • Verilog队列链表操作
    链表在缓存管理中有重要的应用,对所有输入的数据都放在一块大的RAM中缓存,并且根据一定的规则将数据分类并划归不同的队列,不同队列的数据可以分别控制输出,队列内,数据按严格先进先出的顺序操作我们假设输入数据的位宽为256,并且开辟一个2^20深度的RAM用于缓存,那么RAM大小为32MB。将......
  • 01-复杂度3 二分查找 陈越、何钦铭数据结构
    题目可以满分通过的答案:`PositionBinarySearch(ListL,ElementTypeX){Positionleft=1;Positionright=L->Last;while(left<=right){Positioncenter=(left+right)/2;if(L->Data[center]>X){right=center-1;}elseif(L->Data......
  • 教你如何手撕双向链表
    1.双向链表1.1概念与结构注意:这⾥的“带头”跟前⾯我们说的“头结点”是两个概念,实际前⾯的在单链表阶段称呼不严谨,但是为了同学们更好的理解就直接称为单链表的头结点。带头链表⾥的头结点,实际为“哨兵位”,哨兵位结点不存储任何有效元素,只是站在这⾥“放哨......
  • 数据结构-C语言-排序(3)
            代码位置:test-c-2024:对C语言习题代码的练习(gitee.com)一、前言:1.1-排序定义:        排序就是将一组杂乱无章的数据按照一定的规律(升序或降序)组织起来。(注:我们这里的排序采用的都为升序)1.2-排序分类:常见的排序算法:插入排序a. 直接插......
  • (算法)合并两个有序链表————<递归>
    1.题⽬链接:21.合并两个有序链表 2.题⽬描述: 3.解法(递归):算法思路:1.递归函数的含义:交给你两个链表的头结点,你帮我把它们合并起来,并且返回合并后的头结点;2.函数体:选择两个头结点中较⼩的结点作为最终合并后的头结点,然后将剩下的链表交给递归函数去处理;3.递归出......
  • 数据结构:基础概念
    一、相关概念概念相互之间存在一种或多种特定关系的数据元素的集合。逻辑结构集合:所有数据在同一个集合中,关系平等。线性:数据和数据之间是一对一的关系树: 一对多图:多对多物理结构(在内存当中的存储关系)顺序存储:数据存放在连续的存储单位中(数组),逻辑关系和物理关......
  • 数据结构与算法从淬体到元婴day04之堆
    堆堆的定义堆是一种特殊的完全二叉树结构,其每个节点的值都遵循一定的堆属性。堆在物理上是通过数组实现的,逻辑上则表现为树形结构。堆的性质堆总是一棵完全二叉树。堆中某个节点的值总是不大于(最大堆)或不小于(最小堆)其父节点的值。将根节点最大的堆称为最大堆或大根堆,根节点......
  • Redis底层数据结构-简单动态字符串SDS
    简单动态字符串(simpledynamicstring,SDS)。Redis没有直接使用C语言传统的字符串,而是自己构建了一种简单动态字符串(SDS)的抽象类型。C字符串只会作为字符串字面量(stringliteral)用在一些无须对字符串值进行修改的地方。实现sds.h/sdshdrstruct__attribute__((__packed__)......