zoukankan      html  css  js  c++  java
  • 双向循环链表实践

    题目:

      要求实现用户输入一个数使得26个字母的排列发生变化,例如用户输入3,输出结果:

      DEFGHIJKLMNOPQRSTUVWXYZABC

      同时需要支持负数,例如用户输入-3,输出结果:

      XYZABCDEFGHIJKLMNOPQRSTUVW

    -----------------------------------------------------------------------------------------------------------------------------

    首先,我们要明白什么叫双向循环链表,双向,也就是有pre和next,循环也就是首尾相连,那么我们把双向循环链表设计成这样

    public class MyLoopLinkedList<E> {
        private Node<E> head;
    
        public MyLoopLinkedList() {
            super();
        }
    
        /**
         * 添加元素,默认添加到尾部
         * 
         * @param e
         */
        public void add(E e) {
            if (head == null) {
                head = new Node<E>(null, e, null);
            } else {// 将首尾相连
                Node<E> n = new Node<E>(null, e, null);
                if (head.pre == null) {//
                    head.pre = n;
                    head.next = n;
                    n.next = head;
                    n.pre = head;
                } else {
                    Node<E> last = head.pre;
                    last.next = n;
                    n.pre = last;
                    n.next = head;
                    head.pre = n;
                }
            }
        }
    
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("[").append(head.item).append(",");
            for (Node<E> n = head.next; head.next != null && n != head; n = n.next) {
                sb.append(n.item).append(",");
            }
            sb.deleteCharAt(sb.length() - 1).append("]");
            return sb.toString();
        }
    
        private static class Node<E> {
            E item;
            Node<E> pre;
            Node<E> next;
    
            Node(Node<E> pre, E element, Node<E> next) {
                this.pre = pre;
                this.item = element;
                this.next = next;
            }
        }
    }

    这里我把第一个添加的元素作为头部,测试一下是否符合可以

        public static void main(String[] args){
            MyLoopLinkedList<String> list=new MyLoopLinkedList<>();
            list.add("A");
            list.add("B");
            list.add("C");
            list.add("D");
            list.add("E");
            list.add("F");
            list.add("G");
            list.add("H");
            list.add("I");
            list.add("J");
            list.add("K");
            list.add("L");
            list.add("M");
            list.add("N");
            list.add("O");
            list.add("P");
            list.add("Q");
            list.add("R");
            list.add("S");
            list.add("T");
            list.add("U");
            list.add("V");
            list.add("W");
            list.add("X");
            list.add("Y");
            list.add("Z");
            System.out.println(list.toString());
        }

    输出结果:

    ok,没问题,那么回到正题,要求输入一个3,就从第三个数开始读起,并且支持负数,那么我个人想到了两个解决方案

    ①直接改变头部,代码如下

    /**
         * 更变头部
         * 
         * @param position
         */
        public void changeHead(int position) {
            for (int i = 0; i < Math.abs(position); i++) {
                if (position > 0) {
                    head = head.next;
                } else {
                    head = head.pre;
                }
            }
        }

    将上面的代码添加到MyLoopLinkedList.java里面

    测试代码

    public static void main(String[] args){
            MyLoopLinkedList<String> list=new MyLoopLinkedList<>();
            list.add("A");
            list.add("B");
            list.add("C");
            list.add("D");
            list.add("E");
            list.add("F");
            list.add("G");
            list.add("H");
            list.add("I");
            list.add("J");
            list.add("K");
            list.add("L");
            list.add("M");
            list.add("N");
            list.add("O");
            list.add("P");
            list.add("Q");
            list.add("R");
            list.add("S");
            list.add("T");
            list.add("U");
            list.add("V");
            list.add("W");
            list.add("X");
            list.add("Y");
            list.add("Z");
            System.out.println(list.toString());
            list.changeHead(3);
            System.out.println(list.toString());
        }

    测试结果:

    ②添加一个成员变量,设置读取的初始位置,修改toString方法

    private int readLocation = 0;//读取位置
    
        public void setReadLocation(int readLocation) {
            this.readLocation = readLocation;
        }
    
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            Node<E> readNode = getReadNode();
            sb.append("[").append(readNode.item).append(",");
            for (Node<E> n = readNode.next; readNode.next != null && n != readNode; n = n.next) {
                sb.append(n.item).append(",");
            }
            sb.deleteCharAt(sb.length() - 1).append("]");
            return sb.toString();
        }
        /**
         * 确定读取元素位置
         * @return
         */
        private Node<E> getReadNode() {
            Node<E> readNode = head;
            for (int i = 0; i < Math.abs(readLocation); i++) {
                if (readLocation > 0) {
                    readNode = readNode.next;
                } else if (readLocation < 0) {
                    readNode = readNode.pre;
                }
            }
            return readNode;
        }

    测试代码

    public static void main(String[] args){
            MyLoopLinkedList<String> list=new MyLoopLinkedList<>();
            list.add("A");
            list.add("B");
            list.add("C");
            list.add("D");
            list.add("E");
            list.add("F");
            list.add("G");
            list.add("H");
            list.add("I");
            list.add("J");
            list.add("K");
            list.add("L");
            list.add("M");
            list.add("N");
            list.add("O");
            list.add("P");
            list.add("Q");
            list.add("R");
            list.add("S");
            list.add("T");
            list.add("U");
            list.add("V");
            list.add("W");
            list.add("X");
            list.add("Y");
            list.add("Z");
            System.out.println(list.toString());
            list.setReadLocation(-3);
            System.out.println(list.toString());
        }

    测试结果:

    总结:两种方法我比较推荐使用第二种方法,第一种方法会导致第一次添加元素的信息掉额失,而第二种方法并没有动head成员变量,并且没有影响之前的使用

  • 相关阅读:
    [EOJ]2019 ECNU XCPC March Selection #1
    [模板]宏定义
    [POJ]poj1961,poj2406(KMP)
    [模板]KMP
    [CF]Avito Cool Challenge 2018
    [CF]Codeforces Round #528 Div.2
    [POJ]POJ1328(贪心)
    洛谷 P3808 【模板】AC自动机(简单版) 题解
    中科院的难题 题解
    【转】洛谷 P3722 [AH2017/HNOI2017]影魔 题解
  • 原文地址:https://www.cnblogs.com/pig-brother/p/7348280.html
Copyright © 2011-2022 走看看