• 实现双向链表


    双向链表和单向链表相比更加灵活,它的每一个元素除了本身的值以为拥有两个指针,分别指向上一个和下一个节点。维护成本上要高于单向链表。链表的大部分操作依赖于遍历,这一方面双向链表会效率会好一些,可以根据查询下标的位置从而选择从链表头开始遍历还是从链表尾开始遍历。

    package com.dfsn.cloud.eureka;
    
    public class BothwayLinkedList<T> {
        // 头节点
        private Node first;
    
        // 尾节点
        private Node last;
    
        // 元素个数
        private int size = 0;
    
        // 增加元素
        public void add(T t) {
            if (first == null) {
                Node newNode = new Node(t, null, null);
                first = newNode;
                last = newNode;
            } else {
                Node newLast = new Node(t, null, last);
                last.next = newLast;
                last = newLast;
            }
            size++;
        }
    
        // 返回元素个数
        public int size() {
            return size;
        }
    
        // 遍历链表
        public void show() {
            if (first == null) {
                throw new RuntimeException("链表为空");
            } else {
                Node temp = first;
                while (true) {
                    System.out.println(temp);
                    if (temp.next == null) {
                        break;
                    }
                    temp = temp.next;
                }
    
            }
        }
    
        // 根据下标获取节点
        public T get(int index) {
            return get(index, "").item;
        }
    
        private Node get(int index, String s) {
            if (first == null) {
                throw new RuntimeException("链表为空,没有对应节点");
            } else if (index >= size) {
                throw new RuntimeException("链表长度为:" + size + ",index为" + (size - 1));
            } else if (index < 0) {
                throw new RuntimeException("下标不能<0");
            } else {
                int avg = size / 2;
                if (index < avg) {
                    Node temp = first;
                    for (int i = 0; i < index; i++) {
                        temp = temp.next;
                    }
                    return temp;
                } else {
                    Node temp = last;
                    for (int i = size - 1; i > index; i--) {
                        temp = temp.prev;
                    }
                    return temp;
                }
            }
        }
    
        // 在指定位置插入
        public void add(int index, T t) {
            if (index > size) {
                throw new RuntimeException("链表长度为:" + size + ",index为" + size);
            } else if (index < 0) {
                throw new RuntimeException("下标不能<0");
            } else if (index == 0) {
                Node newNode = new Node(t, first, null);
                newNode.next = first;
                first = newNode;
            } else if (index == size) {
                Node newNode = new Node(t, null, last);
                last.next = newNode;
                last = newNode;
            } else {
                // 原来位置的node
                Node node = get(index, "");
                Node newNode = new Node(t, node, node.prev);
                node.prev.next = newNode;
                node.prev = newNode;
            }
            size++;
        }
    
        // 更改指定位置的元素
        public void set(int index, T t) {
            if (index >= size) {
                throw new RuntimeException("链表长度为:" + size + ",index为" + (size - 1));
            } else if (index < 0) {
                throw new RuntimeException("下标不能<0");
            } else {
                Node node = get(index, "");
                node.item = t;
            }
        }
    
        // 删除指定位置的元素
        public void remove(int index) {
            if (index >= size) {
                throw new RuntimeException("链表长度为:" + size + ",index为" + (size - 1));
            } else if (index < 0) {
                throw new RuntimeException("下标不能<0");
            } else if (index == 0) {
                first = first.next;
                first.prev = null;
            } else if (index == size - 1) {
                last = last.prev;
                last.next = null;
            } else {
                Node node = get(index, "");
                Node next = node.next;
                Node prev = node.prev;
                prev.next = next;
                next.prev = prev;
            }
            size--;
        }
    
        // 返回头节点
        public T getFirst() {
            return first.item;
        }
    
        // 返回尾节点
        public T getLasts() {
            return last.item;
        }
    
        // 节点对象
        class Node {
            private T item;
            private Node next;
            private Node prev;
    
            public Node(T item, Node next, Node prev) {
                this.item = item;
                this.next = next;
                this.prev = prev;
            }
    
            @Override
            public String toString() {
                return "Node [item=" + item + "]";
            }
    
        }
    }
    View Code
  • 相关阅读:
    【项目 · Wonderland】UML设计
    【项目 · Wonderland】预则立 && 他山之石
    【项目 · Wonderland】需求规格说明书 · 终版
    【项目 · 学生部门互选系统】项目展示
    【项目 · Wonderland】立项报告
    React 封装Form表单组件
    前端算法题解析 《四》
    前端算法题解析 《三》
    前端算法题解析 《二》
    前端算法题解析 《一》
  • 原文地址:https://www.cnblogs.com/zumengjie/p/13776844.html
Copyright © 2020-2023  润新知