1.3数据结构学习-链表

链表

1.描述:链表是一种链式存储有序列表
2.存储方式:链式存储,以节点方式存储,每个节点包含数据域及指向下一个节点的引用
3.内存分布:存储的每个节点在内存中并不连续
4.种类:
	1).单向链表:节点中仅包含指向下一个节点的引用
	2).双向链表:节点中包含指向下一个节点的引用及指向上一个节点的引用

单向链表

单向链表DEMO

/**
 * @Auther: LiXuHui
 * @Date: 2019/7/17/017 13:50
 * @Description:
 */
@Getter
@Setter
public class LinkList<T>
{
    /**
     * 头节点
     */
    private Node<T> head;
    /**
     * 尾节点
     */
    private Node<T> last;
    /**
     * @param value 被插入元素
     * @return void
     * @desc : 插入元素到头部
     * 1.生成节点
     * 2.如头节点不存在,则将头节点尾节点均指向当前生成节点,结束
     * 3.生成节点的next引用指向当前头节点
     * 4.头节点指向当前生成节点
     * @author lxh
     * @date 2021/5/22 0022 16:35
     **/
    public void insertHead(T value)
    {
        Node<T> node = new Node<T>(value);
        if (head == null)
        {
            head = node;
            last = node;
        }
        else
        {
            node.setNext(head);
        }
        head = node;
    }
    /**
     * @param value 被插入元素
     * @return void
     * @desc : 插入元素到尾部
     * 1.生成节点
     * 2.如头节点不存在,则将头节点尾节点均指向当前生成节点
     * 3.当前尾节点的next引用指向当前生成节点
     * 4.尾节点指向当前生成节点
     * @author lxh
     * @date 2021/5/22 0022 16:35
     **/
    public void insertLast(T value)
    {
        Node<T> node = new Node<T>(value);
        if (head == null)
        {
            head = node;
            last = node;
        }
        else
        {
            last.setNext(node);
        }
        last = node;
    }
    /**
     * @param value 被插入元素
     * @return void
     * @desc : 按照下标插入元素
     * 1.生成节点
     * 2.1.如预插入下标=0,则直接插入元素到头部即可,结束
     * 2.2.如预插入下标!=0,则找到该下标的上一个位置,如未找到则找到最后一个节点,将其作为前置节点
     * 3.将生成节点的next指向前置节点的next
     * 4.将前置节点的next指向生成节点
     * 5.判断生成节点的next是否未空,为空则将作为尾节点
     * @author lxh
     * @date 2021/5/22 0022 16:35
     **/
    public void insert(T value, int pos)
    {
        if (pos == 0)
        {
            insertHead(value);
        }
        else
        {
            Node node = new Node(value);

            Node currentNode = head;
            for (int i = 1; i < pos && currentNode.getNext() != null; i++)
            {
                currentNode = currentNode.getNext();
            }
            node.setNext(currentNode.getNext());
            currentNode.setNext(node);
            if (node.getNext() == null)
            {
                last = node;
            }
        }
    }
    /**
     * @param value 被查找目标元素
     * @return void
     * @desc : 删查找指定元素
     * 依次便利next判断其data进行查找
     * @author lxh
     * @date 2021/5/22 0022 16:38
     **/
    public Node find(T value)
    {
        Node<T> currentNode = head;
        while (currentNode != null)
        {
            if (value == currentNode.getData())
            {
                return currentNode;
            }
            currentNode = currentNode.getNext();
        }
        return null;
    }
    /**
     * @param value 被删除目标元素
     * @return void
     * @desc : 删除指定元素
     * 1.判断如删除的元素为首节点,则将首节点指向当前首节点的next引用,结束
     * 2.找到预删除节点及前一个节点未前置节点
     * 3.将前置节点的next引用指向预删除节点的next
     * 4.如此时前置节点next引用为null,即删除了尾节点,则将前置节点作为尾节点
     * @author lxh
     * @date 2021/5/22 0022 16:38
     **/
    public void delete(T value)
    {
        Node currentNode = head;
        if (currentNode.data == value)
        {
            head = head.getNext();
            return;
        }
        while (currentNode.getNext() != null)
        {
            if (currentNode.getNext().getData() == value)
            {
                Node delNode = currentNode.getNext();
                currentNode.setNext(delNode.getNext());
                if (null == currentNode.getNext())
                {
                    last = currentNode;
                }
                return;
            }
            currentNode = currentNode.getNext();
        }
    }
    /**
     * @return void
     * @desc : 便利展示链表元素
     * @author lxh
     * @date 2021/5/22 0022 16:37
     **/
    public void disploy()
    {
        Node currentNode = head;
        while (currentNode != null)
        {
            System.out.print(currentNode.getData() + " ");
            currentNode = currentNode.getNext();
        }
        System.out.println();
    }

    /**
     * @Auther: LiXuHui
     * @Date: 2019/7/17/017 13:49
     * @Description:
     */
    @Getter
    @Setter
    public static class Node<T>
    {
        /**
         * 数据存储模型
         */
        private T data;
        /**
         * 下一节点引用
         */
        private Node<T> next;

        public Node(T data)
        {
            this.data = data;
        }
    }
    public static void main(String[] args)
    {
        System.out.println("---------------------");
        Random random = new Random();
        LinkList linkList = new LinkList<Integer>();
        for (int i = 0; i < 5; i++)
        {
            Integer value = random.nextInt(50);
            System.out.println("尾部加入元素: " + value);
            linkList.insertLast(value);
        }
        System.out.println("---------------------");
        for (int i = 0; i < 5; i++)
        {
            Integer value = random.nextInt(50);
            System.out.println("头部加入元素: " + value);
            linkList.insertHead(value);
        }
        System.out.println("---------------------");
        System.out.println("链表元素为");
        linkList.disploy();
        System.out.println("---------------------");
        linkList.insert(99, 13);
        linkList.insert(100, 3);
        System.out.println("依照下标[3]加入元素[99][100],链表元素为");
        linkList.disploy();
        System.out.println("---------------------");
        System.out.println("删除指定元素[99],链表元素为");
        linkList.delete(99);
        linkList.disploy();
        System.out.println("-----------------------");
        System.out.println("查询指定元素100 :" + linkList.find(100).getData());
        System.out.println("-----------------------");
    }
}

结果

---------------------
尾部加入元素: 29
尾部加入元素: 12
尾部加入元素: 34
尾部加入元素: 17
尾部加入元素: 7
---------------------
头部加入元素: 49
头部加入元素: 42
头部加入元素: 18
头部加入元素: 46
头部加入元素: 18
---------------------
链表元素为
18 46 18 42 49 29 12 34 17 7 
---------------------
依照下标[3]加入元素[99][100],链表元素为
18 46 18 100 42 49 29 12 34 17 7 99 
---------------------
删除指定元素[99],链表元素为
18 46 18 100 42 49 29 12 34 17 7 
-----------------------
查询指定元素100 :100
-----------------------


双向链表

双向链表DEMO

/**
 * @Auther: LiXuHui
 * @Date: 2019/7/17/017 13:50
 * @Description:
 */
@Getter
@Setter
public class DoubleLinkList<T>
{
    /**
     * 头节点
     */
    private Node<T> head;
    /**
     * 尾节点
     */
    private Node<T> last;
    /**
     * @param value 被插入元素
     * @return void
     * @desc : 插入元素到头部
     * 1.生成节点
     * 2.如头节点不存在,则将头节点尾节点均指向当前生成节点,结束
     * 3.生成节点的next引用指向当前头节点,当前头节点pre引用指向生成节点
     * 4.头节点指向当前生成节点
     * @author 李旭辉
     * @date 2021/5/22 0022 16:35
     **/
    public void insertHead(T value)
    {
        Node<T> node = new Node<T>(value);
        if (head == null)
        {
            head = node;
            last = node;
        }
        else
        {
            node.setNext(head);
            head.setPre(node);
        }
        head = node;
    }
    /**
     * @param value 被插入元素
     * @return void
     * @desc : 插入元素到尾部
     * 1.生成节点
     * 2.如头节点不存在,则将头节点尾节点均指向当前生成节点
     * 3.当前尾节点的next引用指向当前生成节点,生成节点pre指向当前尾节点
     * 4.尾节点指向当前生成节点
     * @author 李旭辉
     * @date 2021/5/22 0022 16:35
     **/
    public void insertLast(T value)
    {
        Node<T> node = new Node<T>(value);
        if (head == null)
        {
            head = node;
            last = node;
        }
        else
        {
            last.setNext(node);
            node.setPre(last);
        }
        last = node;
    }

    /**
     * @param value 被插入元素
     * @return void
     * @desc : 按照下标插入元素
     * 1.生成节点
     * 2.1.如预插入下标=0,则直接插入元素到头部即可,结束
     * 2.2.如预插入下标!=0,则找到该下标的上一个位置,如未找到则找到最后一个节点,将其作为前置节点
     * 4.取前置节点的next作为后置节点
     * 4.1若后置节点为空则说明前置节点是最后一个节点,将前置节点的next指向生成节点,并将生成节点作为尾节点
     * 4.2若后置节点为空则说明前置节点非最后一个节点,将前置节点的next指向生成节点,后置节点的pre指向生成节点
     * 5.将生成节点的next指向后置节点,生成节点的pre指向前置节点
     * @author 李旭辉
     * @date 2021/5/22 0022 16:35
     **/
    public void insert(T value, int pos)
    {
        if (pos == 0)
        {
            insertHead(value);
        }
        else
        {
            Node node = new Node(value);
            Node currentNode = head;
            for (int i = 1; i < pos && currentNode.getNext() != null; i++)
            {
                currentNode = currentNode.getNext();
            }
            Node nextNode = currentNode.getNext();

            node.setPre(currentNode);
            currentNode.setNext(node);

            node.setNext(nextNode);
            if (nextNode == null)
            {
                last = node;
            }
            else
            {
                nextNode.setPre(node);
            }
        }
    }
    /**
     * @param value 被查找目标元素
     * @return void
     * @desc : 双向查找指定元素
     * 依次便利next判断其data进行查找
     * @author 李旭辉
     * @date 2021/5/22 0022 16:38
     **/
    public Node find(T value)
    {
        Node<T> preNode = head;
        Node<T> lastNode = last;
        while (preNode != lastNode)
        {
            if (value == preNode.getData())
            {
                return preNode;
            }
            if (value == lastNode.getData())
            {
                return lastNode;
            }
            preNode = preNode.getNext();
            lastNode = lastNode.getPre();
        }
        return null;
    }
    /**
     * @param value 被删除目标元素
     * @return void
     * @desc : 删除指定元素
     * 1.找到该节点
     * 2.判断该节点pre前节点及next后节点
     * 2.1若前置节点为空,说明该节点为首节点,删除该节点需将后置节点作为首节点,并将后置节点的pre置为空
     * 2.1若后置节点为空,说明该节点为尾节点,删除该节点需将前置节点作为尾节点,并将前置节点的next置为空
     * 2.3若均不为空,则将前节点的next指向后节点,后节点的pre指向前节点(越过待删除节点)
     * @author 李旭辉
     * @date 2021/5/22 0022 16:38
     **/
    public void delete(T value)
    {
        Node deleteNode = find(value);
        if (deleteNode == null)
        {
            return;
        }
        Node pre = deleteNode.getPre();
        Node next = deleteNode.getNext();
        if (pre == null)
        {
            next.setPre(null);
            head = next;
        }
        else if (next == null)
        {
            pre.setNext(null);
            last = pre;
        }
        else
        {
            pre.setNext(next);
            next.setPre(pre);
        }
    }
    /**
     * @return void
     * @desc : 便利展示链表元素
     * @author 李旭辉
     * @date 2021/5/22 0022 16:37
     **/
    public void disploy()
    {
        Node currentNode = head;
        while (currentNode != null)
        {
            System.out.print(currentNode.getData() + " ");
            currentNode = currentNode.getNext();
        }
        System.out.println();
    }

    /**
     * @Auther: LiXuHui
     * @Date: 2019/7/17/017 13:49
     * @Description:
     */
    @Getter
    @Setter
    public static class Node<T>
    {
        /**
         * 数据存储模型
         */
        private T data;
        /**
         * 下一节点引用
         */
        private Node<T> next;
        /**
         * 上一节点引用
         */
        private Node<T> pre;

        public Node(T data)
        {
            this.data = data;
        }
    }
    public static void main(String[] args)
    {
        DoubleLinkList linkList = new DoubleLinkList<Integer>();
        System.out.println("---------------------");
        for (int i = 0; i < 5; i++)
        {
            int value = new Random().nextInt(50);
            System.out.println("尾部加入元素: " + value);
            linkList.insertLast(value);
        }
        System.out.println("---------------------");
        for (int i = 0; i < 5; i++)
        {
            int value = new Random().nextInt(50);
            System.out.println("头部加入元素: " + value);
            linkList.insertHead(value);
        }
        System.out.println("---------------------");
        System.out.println("链表元素为");
        linkList.disploy();
        System.out.println("---------------------");
        linkList.insert(99, 3);
        linkList.insert(100, 3);
        System.out.println("依照下标[3]加入元素[99][100],链表元素为");
        linkList.disploy();
        System.out.println("---------------------");
        System.out.println("删除指定元素[99],链表元素为");
        linkList.delete(99);
        linkList.disploy();
        System.out.println("-----------------------");
        System.out.println("查询指定元素100 :" + linkList.find(100).getData());
        System.out.println("-----------------------");
    }
}

结果

---------------------
尾部加入元素: 9
尾部加入元素: 44
尾部加入元素: 45
尾部加入元素: 11
尾部加入元素: 7
---------------------
头部加入元素: 41
头部加入元素: 21
头部加入元素: 36
头部加入元素: 6
头部加入元素: 5
---------------------
链表元素为
5 6 36 21 41 9 44 45 11 7 
---------------------
依照下标[3]加入元素[99][100],链表元素为
5 6 36 100 99 21 41 9 44 45 11 7 
---------------------
删除指定元素[99],链表元素为
5 6 36 100 21 41 9 44 45 11 7 
-----------------------
查询指定元素100 :100
-----------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值