3.线性表(二,线性表的链式存储结构,链式基数排序)

链式基数排序

说明:

适用于棋牌游戏发牌之后的排序,数量在十几到二十几之间

思路:

服务端发的牌是无序的,我们需要将牌按照花色和点数排列

  1. 按照点数创建9个单链表(对应麻将中一万到九万,一饼到九饼,一条到九条),将服务器发下的牌按照点数分别放进这9个单链表中,再将这9个单链表连接成1个单链表
  2. 按照花色创建3个单链表(对应麻将中饼子,万字,条子),将2处理好的链表按照花色分别放进这3个单链表中,再讲这3个单链表链接成一个单链表
代码:
public class Mahjong {

    private int rank;//点数
    private int suit;//花色

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

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public int getSuit() {
        return suit;
    }

    public void setSuit(int suit) {
        this.suit = suit;
    }

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

import org.junit.Test;

import java.util.LinkedList;

public class RadixSort {

    public void radixSort(LinkedList list){

        LinkedList[] rankList = new LinkedList[9];

        for (int i = 0; i < 9; i++) {
            rankList[i] = new LinkedList<>();
        }

        while (list.size()!=0){
            Mahjong m = list.remove();
            rankList[m.getRank()-1].add(m);
        }

        for (LinkedList mahjongs : rankList) {
            list.addAll(mahjongs);
        }

        LinkedList[] suitList = new LinkedList[3];

        for (int i = 0; i < 3; i++) {
            suitList[i] = new LinkedList<>();
        }

        while(list.size()!=0){
            Mahjong m = list.remove();
            suitList[m.getSuit()-1].add(m);
        }

        for (LinkedList mahjongs : suitList) {
            list.addAll(mahjongs);
        }

    }

    @Test
    public void test(){
        LinkedList list=new LinkedList();
        list.add(new Mahjong(3,1));
        list.add(new Mahjong(2,3));
        list.add(new Mahjong(3,7));
        list.add(new Mahjong(1,1));
        list.add(new Mahjong(3,8));
        list.add(new Mahjong(2,2));
        list.add(new Mahjong(3,2));
        list.add(new Mahjong(1,3));
        list.add(new Mahjong(3,9));
        System.out.println(list);
        radixSort(list);
        System.out.println(list);
    }
}

链表:

特点:

查询比较慢,需要逐个结点去遍历,添加和删除比较快,只需要改变前驱和后继的索引不需要去移动其他节点

单链表

特点:

除尾结点(最后一个结点)外,每个节点都有后继节点

/**
 * 单链表
 */
public class SingleLinkList {

    class Node {
        E element;
        Node next;

        public Node(E element, Node next) {
            this.element = element;
            this.next = next;
        }
    }

    Node first;
    Node last;
    int size;

    /**
     * 尾部添加
     *
     * @param e
     */
    public void add(E e) {
        Node node = new Node<>(e, null);
        if (last == null) {
            first = node;
            last = node;
        } else {
            Node l = last;
            l.next = node;
            last = node;
        }
        size++;
    }

    /**
     * 获取index位置的结点的值
     *
     * @param index
     * @return
     */
    public E get(int index) {
        if (node(index) != null) {
            return node(index).element;
        } else {
            return null;
        }
    }

    /**
     * 获取index位置结点
     *
     * @param index
     * @return
     */
    private Node node(int index) {
        if (index < 0 || index > size - 1) {
            return null;
        } else {
            Node node = first;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
            return node;
        }
    }

    public void add(int index, E e) {
        if (index < 0||index>size) {
            return;
        } else {
            Node target = node(index);
            Node node = new Node<>(e, target);
            if (target == null) {
                last = node;
            }

            Node pre = node(index - 1);
            if (pre != null) {
                pre.next = node;
            } else {
                first = node;
            }

            size++;
        }
    }

    public void remove(){
        Node pre = node(size-1);
        if (pre!=null){
            pre.next = null;
            last = pre;
            size--;
        }else {
            first = null;
            last = null;
        }
    }

    public void remove(int index){
        if (index<0||index>size-1){
            return;
        }else {
            Node target = node(index);
            Node next = target.next;
            target.next = null;
            Node pre = node(index-1);
            if (pre!=null){
                pre.next=next;
            }else {
                first = next;
            }
            size--;
        }
    }
}

双向链表

特点:

除头结点(第一个结点)外,每个节点都有前驱结点,除尾结点(最后一个结点)外,每个节点都有后继节
点.相比于单链表,双链表可以从后往前遍历,查找速度要快

/**
 * 双向链表类
 * @param 
 */
public class LinkedList {

    /**
     * 节点类
     * @param 
     */
    class Node {

        Node pre;
        E element;
        Node next;

        public Node(Node pre, E element, Node next) {
            this.pre = pre;
            this.element = element;
            this.next = next;
        }
    }

    Node first;//头结点
    Node last;//尾节点
    int size;//大小

    /**
     * 尾部添加结点
     * @param e
     */
    public void add (E e){
        Node node = new Node<>(last,e,null);
        linkLast(node);
    }

    private void linkLast(Node node) {
        if (last==null){
            first = node;
        }else {
            Node l = last;
            l.next = node;
        }
        last = node;
        size++;
    }

    public E get (int index){
        if (node(index)!=null){
            return node(index).element;
        }
        return null;
    }

    /**
     * 查找对应位置的结点
     * @param index
     * @return
     */
    public Node node(int index){
        if (index<0||index>size-1){
            return null;
        }else {
            if (index node = first;
                for (int i = 0; i < index; i++) {
                    node = node.next;
                }
                return node;
            }else {
                Node node = last;
                for (int i = size; i > index; i--) {
                    node = node.pre;
                    return node;
                }
            }

        }
        return null;
    }

    public void add(int index,E e){
        if (index<0){
            return;
        }else if (index>size){
            index = size+1;
        }
            Node next = node(index);
            Node pre = null;
            if (next!=null){
                pre = next.pre;
            }else {
                pre = last;
            }

            Node node = new Node<>(pre,e,next);

            if (pre!=null){
                pre.next = node;
            }else {
                first = node;
            }

            if (next!=null){
                next.pre = node;
            }else {
                last = node;
            }
            size++;
    }

    /**
     * 移除尾节点
     */
    public void remove(){
        if (size==0){
            return;
        }else {
            Node pre = last.pre;
            Node l = last;
            if (pre!=null){
                pre.next = null;
                l.pre = null;
                last = pre;
            }else {
                first = null;
                last = null;
            }
        }
        size--;
    }

    /**
     * 移除index位置的结点
     * @param index
     */
    public void remove(int index){
        if (index<0||index>size-1){
            return;
        }else {
            Node target = node(index);
            Node pre =  target.pre;
            Node next = target.next;

            if (pre!=null){
                pre.next = next;
            }else {
                first = next;
            }

            target.next = null;
            target.pre = null;

            if (next!=null){
                next.pre = pre;
            }else {
                last = pre;
            }

        }
        size--;
    }

}

你可能感兴趣的:(3.线性表(二,线性表的链式存储结构,链式基数排序))