• 双向链表实现


    双向链表和我们前面讲的单链表最大的区别就是多了一个前驱结点

    我们第一步还是定义Sequence接口,它里面都是双向链表一些基本的操作,增删查改等

    Sequence接口定义如下:

    public interface Sequence {
        
        /**
         * 向线性表中添加元素
         * @param date   要存储的元素
         */
        void add(Object date);
        
        /**
         * 线性表中删除元素
         * @param index   要删除的元素下标
         * @return  是否删除成功
         */
        boolean remove(int index);
        
        /**
         * 在线性表中查找指定下标的元素
         * @param index   要查找的索引
         * @return
         */
        Object get(int index);
        
        /**
         * 判断线性表中是否有指定元素
         * @param data   要查找的元素内容
         * @return
         */
        boolean contains(Object data);
        
        /**
         * 修改线性表中指定索引的内容
         * @param index   要修改元素下标
         * @param newData  修改后的内容
         * @return
         */
        Object set(int index,Object newData);
        
        /**
         * 返回当前线性表的长度
         * @return
         */
        int size();
        
        /**
         * 清空线性表内容
         */
        void clear();
        
        /**
         * 将线性表转为数组
         * @return
         */
        Object[] toArray();

    下面是双向链表类中实现Sequence接口的方法实现:

    首先我们先定义DoubleLinkListImpl类,

    public class DoubleLinkedListImpl implements Sequence{
    
        //表示头结点
        private ListNode head;
        //表示尾结点
        private ListNode tail;
            //链表长度
        private int size;
            //内部类ListNode
        private class ListNode {
            private ListNode prev;
            private ListNode next;
            Object data;
            public ListNode(ListNode prev , Object data, ListNode next) {
                this.prev = prev;
                this.next = next;
                this.data = data;
            }
            public ListNode(Object data) {
                this.data = data;
            }
            
        }
    }

    该类中具体实现方法我们一步一步写出来:

    checkIndex方法:

    //检查索引index是否合法
        private void checkIndex(int index) {
            if(index < 0 || index >= size) {
                throw new IndexOutOfBoundsException("Illeagle Index");
            }
        }

    node方法:

    //获取当前索引结点
    private
    ListNode node(int index) { ListNode tmp = head; for(int i = 0;i<index;i++) { tmp = tmp.next; } return tmp; }

    add方法:

    /**
         * 尾插法
         */
        public void add(Object date) {
            // TODO Auto-generated method stub
            ListNode node = new ListNode(tail,date,null);
            if(head == null) {
                head = node;
            }else {
                tail.next = node;
            }
            tail = node;
            size++;
            
        }

    remove方法:

    public boolean remove(int index) {
            // TODO Auto-generated method stub
            checkIndex(index);
            //要删除结点
            ListNode now = node(index);
            ListNode prevNode = now.prev;
            ListNode nextNode = now.next;
            //要删除的是头结点
            if(prevNode == null) {
                head = nextNode;
            }else {
                prevNode.next = now.next;
                now.prev = null;
            }
            //要删除的是尾结点
            if(nextNode == null) {
                tail = now.prev;
            }else {
                nextNode.prev = now.prev;
                now.prev = null;
            }
            size--;
            return true;
        }

    get方法:

    public Object get(int index) {
            // TODO Auto-generated method stub
            checkIndex(index);
            return node(index).data;
        }

    contains方法:

    public boolean contains(Object data) {
            // TODO Auto-generated method stub
            ListNode tmp = head;
            while(tmp!=null) {
                if(tmp.data.equals(data)) {
                    return true;
                }
                tmp = tmp.next;
            }
            return false;
        }

    set方法:

    public Object set(int index, Object newData) {
            // TODO Auto-generated method stub
            checkIndex(index);
            ListNode node = node(index);
            node.data = newData;
            return newData;
        }

    clear方法:

        @Override
        public void clear() {
            // TODO Auto-generated method stub
            for(ListNode tmp = head;tmp!=null;) {
                ListNode next = tmp.next;
                tmp.prev = tmp.next = null;
                tmp.data = null;
                tmp = next;
                size--;
            }
            
        }

    size方法:

    public int size() {
            // TODO Auto-generated method stub
            return size;
        }

    toArray方法:

    public Object[] toArray() {
            // TODO Auto-generated method stub
            Object[] object = new Object[size];
            int i = 0;
            for(ListNode tmp = head;tmp!=null;tmp = tmp.next) {
                object[i++] = tmp.data;
            }
            return object;
        }

    完整代码链接:https://github.com/dukaichao/DataStructure/tree/master/dkc_ds_0319

  • 相关阅读:
    【Oracle/PLSQL】没事玩一个简单的表充值程序
    findmnt命令查找已挂载的文件系统
    如何让shell脚本变成可执行文件
    在Linux中如何查看文件的修改日期
    Dutree – Linux上的命令行磁盘使用情况分析工具
    用FRP做内网穿透使用远程桌面连接家里的windows电脑
    Dog-用于DNS查询的命令行工具
    【DeFi】一文读懂预言机原理、类型、现状和发展方向
    Vitalik Buterin 解读 Nathan Schneider 论文:加密经济治理的局限与改进思路
    Vitalik:回顾区块链近 5 年经济学进展,以及新出现的问题
  • 原文地址:https://www.cnblogs.com/du001011/p/10558384.html
Copyright © 2020-2023  润新知