美文网首页数据结构与算法
数据结构与算法(三,线性表的链式存储结构,链式基数排序)

数据结构与算法(三,线性表的链式存储结构,链式基数排序)

作者: 腊鸡程序员 | 来源:发表于2019-01-17 15:35 被阅读23次

    链式基数排序

    说明:

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

    思路:

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

    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<Mahjong> list){
    
            LinkedList<Mahjong>[] 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<Mahjong> mahjongs : rankList) {
                list.addAll(mahjongs);
            }
    
            LinkedList<Mahjong>[] 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<Mahjong> mahjongs : suitList) {
                list.addAll(mahjongs);
            }
    
        }
    
        @Test
        public void test(){
            LinkedList<Mahjong> list=new LinkedList<Mahjong>();
            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<E> {
    
        class Node<E> {
            E element;
            Node<E> next;
    
            public Node(E element, Node<E> next) {
                this.element = element;
                this.next = next;
            }
        }
    
        Node<E> first;
        Node<E> last;
        int size;
    
        /**
         * 尾部添加
         *
         * @param e
         */
        public void add(E e) {
            Node<E> node = new Node<>(e, null);
            if (last == null) {
                first = node;
                last = node;
            } else {
                Node<E> 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<E> node(int index) {
            if (index < 0 || index > size - 1) {
                return null;
            } else {
                Node<E> 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<E> target = node(index);
                Node<E> node = new Node<>(e, target);
                if (target == null) {
                    last = node;
                }
    
                Node<E> 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<E> next = target.next;
                target.next = null;
                Node pre = node(index-1);
                if (pre!=null){
                    pre.next=next;
                }else {
                    first = next;
                }
                size--;
            }
        }
    }
    
    

    双向链表

    特点:

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

    /**
     * 双向链表类
     * @param <E>
     */
    public class LinkedList<E> {
    
        /**
         * 节点类
         * @param <E>
         */
        class Node<E> {
    
            Node<E> pre;
            E element;
            Node<E> next;
    
            public Node(Node<E> pre, E element, Node<E> next) {
                this.pre = pre;
                this.element = element;
                this.next = next;
            }
        }
    
        Node<E> first;//头结点
        Node<E> last;//尾节点
        int size;//大小
    
        /**
         * 尾部添加结点
         * @param e
         */
        public void add (E e){
            Node<E> node = new Node<>(last,e,null);
            linkLast(node);
        }
    
        private void linkLast(Node<E> 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<E> node(int index){
            if (index<0||index>size-1){
                return null;
            }else {
                if (index<size<<2){
                    Node<E> node = first;
                    for (int i = 0; i < index; i++) {
                        node = node.next;
                    }
                    return node;
                }else {
                    Node<E> 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<E> next = node(index);
                Node<E> pre = null;
                if (next!=null){
                    pre = next.pre;
                }else {
                    pre = last;
                }
    
                Node<E> 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<E> target = node(index);
                Node<E> pre =  target.pre;
                Node<E> 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--;
        }
    
    }
    
    

    相关文章

      网友评论

        本文标题:数据结构与算法(三,线性表的链式存储结构,链式基数排序)

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