双向链表

单向链表的缺点分析

  • 单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找。
  • 单向链表不能自我删除,需要靠辅助节点 ,而双向链表,则可以自我删除。
    在这里插入图片描述
    对上图的说明:
  • 遍历方和 单链表一样,只是可以向前,也可以向后查找
  • 添加 (默认添加到双向链表的最后)
    1. 先找到双向链表的最后这个节点
    2. temp.next = newHeroNode
    3. newHeroNode.pre = temp
  • 修改 思路和 原来的单向链表一样
  • 删除
    1. 因为是双向链表,因此,我们可以实现自我删除某个节点
    2. 直接找到要删除的这个节点,比如 temp
    3. temp.pre.next = temp.next
    4. temp.next.pre = temp.pre
/**
 * @date 2021/03/04
 */
public class DoubleLinkedListDemo {
    public static void main(String[] args) {
        DoubleLinkedList<Hero2> linkedList = new DoubleLinkedList<>();
        Hero2 hero1 = new Hero2(1, "宋江", "及时雨");
        Hero2 hero2 = new Hero2(2, "卢俊义", "玉麒麟");
        Hero2 hero3 = new Hero2(3, "吴用", "智多星");
        Hero2 hero4 = new Hero2(4, "林冲", "豹子头");
        Hero2 hero5 = new Hero2(5, "林冲4", "豹子头4");
        Hero2 hero6 = new Hero2(6, "林冲6", "豹子头6");
        Hero2 hero7 = new Hero2(7, "林冲7", "豹子头7");
        Hero2 hero8 = new Hero2(8, "林冲8", "豹子头8");
        Hero2 hero9 = new Hero2(9, "林冲9", "豹子头9");
        System.out.println("尾部插入:");
        linkedList.append(hero1);
        linkedList.append(hero4);
        linkedList.append(hero3);
        linkedList.append(hero2);
        linkedList.show();
        System.out.println("----------------");
        System.out.println("顺序插入:");
        linkedList.clear();
        linkedList.insert(hero1);
        linkedList.insert(hero4);
        linkedList.insert(hero3);
        linkedList.insert(hero2);
        linkedList.insert(hero6);
        linkedList.insert(hero8);
        linkedList.insert(hero5);
        linkedList.insert(hero9);
        linkedList.insert(hero7);
        linkedList.show();
        System.out.println("----------------");
        System.out.println("更新吴用为吴勇:");
        linkedList.update(new Hero2(3, "吴勇", "憨憨"));
        System.out.println("更新林冲为林冲Plus:");
        linkedList.update(new Hero2(4, "林冲Plus", "铁头娃"));
        System.out.println("更新结果:");
        System.out.println(linkedList.query(3));
        System.out.println(linkedList.query(4));
        System.out.println("----------------");
        System.out.println("删除吴勇:");
        System.out.println("删除林冲7:");
        System.out.println("删除林冲9:");
        linkedList.delete(7);
        linkedList.delete(9);
        linkedList.delete(3);
        linkedList.show();
    }
}
class DoubleLinkedList<T> {
    private int size;
    Node<T> head;

    public DoubleLinkedList() {
        this.size = 0;
        // 头结点数据域为空
        this.head = new Node<>(null, null,null);
    }

    /**
     * 在链表尾部添加数据
     *
     * @param data
     */
    public void append(T data) {
        Node<T> tempHead = this.head;
        while (true) {
            // 没有下一个节点了,则在下一个节点插入数据
            if (tempHead.next == null) {
                tempHead.next = new Node<>(data, null,tempHead);
                this.size++;
                break;
            }
            tempHead = tempHead.next;
        }

    }

    /**
     * 插入元素,根据英雄编号从小到大排序
     *
     * @param data
     */
    public void insert(T data) {
        // 若data不是Hero类则不会执行该方法
        if(data.getClass() == Hero2.class){
            Node<T> tempHead = this.head;
            while (true) {
                // 没有下一个节点了,则在下一个节点插入数据
                if (tempHead.next == null) {
                    tempHead.next = new Node<>(data, null,tempHead);
                    this.size++;
                    break;
                }else {
                    Hero2 h1 = (Hero2) data;
                    Hero2 h2 = (Hero2) tempHead.next.item;
                    // 排序
                    if(h1.getNo() <= h2.getNo()){
                        // tempHead.next指向新插入的数据,新插入的数据指向tempHead.next
                        tempHead.next = new Node<>(data, tempHead.next,tempHead);
                        this.size++;
                        break;
                    }
                }
                tempHead = tempHead.next;
            }
        }
        else {
            this.append(data);
        }
    }

    public void update (T data){
        // 更新只针对Hero类
        if (data.getClass() == Hero2.class){
            Node<T> tempHead = this.head;
            while (true){
                if(tempHead.next == null){
                    return;
                }
                Hero2 oldHero = (Hero2) tempHead.next.item;
                Hero2 newHero = (Hero2)data;
                if(oldHero.getNo() ==newHero.getNo()){
                    tempHead.next.item = data;
                    return;
                }
                tempHead = tempHead.next;
            }
        }
    }

    /**
     * 删除
     *
     * @param no
     * @return
     */
    public void delete(int no){
        if(no < 0){
            return ;
        }
        Node<T> tempHead = this.head;
        while (true){
            if(tempHead.next == null){
                return ;
            }
            T t = tempHead.next.item;
            if(t instanceof Hero2){
                Hero2 hero = (Hero2) t;
                if(hero.getNo() == no){
                    if(tempHead.next.next == null){
                        tempHead.next = null;
                    }
                    else {
                        tempHead.next = tempHead.next.next;
                        tempHead.next.pre = tempHead;
                    }
                    this.size--;
                    return ;
                }
            }
            tempHead = tempHead.next;
        }
    }

    /**
     * 查找
     *
     * @param no
     * @return
     */
    public T query(int no){
        if(no < 0){
            return null;
        }
        Node<T> tempHead = this.head;
        while (true){
            if(tempHead.next == null){
                return null;
            }
            T t = tempHead.next.item;
            if(t instanceof Hero2){
                Hero2 hero = (Hero2) t;
                if(hero.getNo() == no){
                    return t;
                }
            }
            tempHead = tempHead.next;
        }
    }
    /**
     * 链表长度
     * @return
     */
    public int size() {
        return this.size;
    }

    /**
     * 查看链表数据
     */
    public void show() {
        Node<T> tempHead = this.head;
        while (tempHead.next != null) {
//            System.out.println("----");
//            System.out.println("pre指针指向:" +tempHead.item);
            System.out.println("当前节点:" +tempHead.next.item);
//            if(tempHead.next.next != null){
//                System.out.println("next指针指向:" + tempHead.next.next.item);
//            }
//            else {
//                System.out.println("next指针指向无数据");
//            }
           tempHead = tempHead.next;
//            System.out.println("----");
        }
    }
    public void clear(){
        this.size = 0;
        // 头结点数据域为空
        this.head = new Node<>(null, null,null);
    }

    /**
     * 链表节点
     *
     * @param <T>
     */
    static private class Node<T> {
        /**
         * 数据域
         */
        T item;
        /**
         * 指向写一个节点
         */
        Node<T> next;
        /**
         * 指向后一个节点
         */
        Node<T> pre;

        public Node(T item, Node<T> next, Node<T> pre) {
            this.item = item;
            this.next = next;
            this.pre = pre;
        }
    }
}

/**
 * 实体类
 *
 */
class Hero2 {
    private int no;
    private String name;
    private String nickname;

    public Hero2(int no, String name, String nickname) {
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }

    public int getNo() {
        return no;
    }


    @Override
    public String toString() {
        return "Hero2{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}

打印内容:

尾部插入:
当前节点:Hero2{no=1, name=‘宋江’, nickname=‘及时雨’}
当前节点:Hero2{no=4, name=‘林冲’, nickname=‘豹子头’}
当前节点:Hero2{no=3, name=‘吴用’, nickname=‘智多星’}
当前节点:Hero2{no=2, name=‘卢俊义’, nickname=‘玉麒麟’}
----------------
顺序插入:
当前节点:Hero2{no=1, name=‘宋江’, nickname=‘及时雨’}
当前节点:Hero2{no=2, name=‘卢俊义’, nickname=‘玉麒麟’}
当前节点:Hero2{no=3, name=‘吴用’, nickname=‘智多星’}
当前节点:Hero2{no=4, name=‘林冲’, nickname=‘豹子头’}
当前节点:Hero2{no=5, name=‘林冲4’, nickname=‘豹子头4’}
当前节点:Hero2{no=6, name=‘林冲6’, nickname=‘豹子头6’}
当前节点:Hero2{no=7, name=‘林冲7’, nickname=‘豹子头7’}
当前节点:Hero2{no=8, name=‘林冲8’, nickname=‘豹子头8’}
当前节点:Hero2{no=9, name=‘林冲9’, nickname=‘豹子头9’}
----------------
更新吴用为吴勇:
更新林冲为林冲Plus:
更新结果:
Hero2{no=3, name=‘吴勇’, nickname=‘憨憨’}
Hero2{no=4, name=‘林冲Plus’, nickname=‘铁头娃’}
----------------
删除吴勇:
删除林冲7:
删除林冲9:
当前节点:Hero2{no=1, name=‘宋江’, nickname=‘及时雨’}
当前节点:Hero2{no=2, name=‘卢俊义’, nickname=‘玉麒麟’}
当前节点:Hero2{no=4, name=‘林冲Plus’, nickname=‘铁头娃’}
当前节点:Hero2{no=5, name=‘林冲4’, nickname=‘豹子头4’}
当前节点:Hero2{no=6, name=‘林冲6’, nickname=‘豹子头6’}
当前节点:Hero2{no=8, name=‘林冲8’, nickname=‘豹子头8’}

学习自尚硅谷

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值