数据结构-链表-双链表

单链表和双链表的区别
单向链表:只有一个指向下一个节点的next指针。查找的方向只能是一个。

优点:单向链表增加删除节点简单。遍历时候不会死循环;

缺点:只能从头到尾遍历。只能找到后继,比较单一。不能自我删除需要辅助节点。

双向链表:有两个指针,一个指向前一个节点prev,一个后一个节点next。可以双向查找。

优点:可以找到前驱和后继,相对单链表灵活一些;可以自我删除。

缺点:增加删除节点复杂,需要多分配一个指针存储空间。

内存示意图
在这里插入图片描述
逻辑结构示意图
在这里插入图片描述
crud实践
遍历和单链表相差不大,就是可以选择向前或者是向后遍历。

  /**
     * 遍历双向链表的方法
     */
    public void list(){
        if (head.next == null){
            System.out.println("此链表为空~~");
            return;
        }
        CharacterNode temp = head.next;
        while (true){
            if (temp == null){
                break;
            }
            System.out.println(temp);
            //将temp后移
            temp = temp.next;
        }
    }
class CharacterNode{
    public int id;
    public String name;
    public String nickname;
    public CharacterNode next;
    public CharacterNode pre;
    public CharacterNode(int id,String name,String nickname){
        this.id = id;
        this.name = name;
        this.nickname = nickname;
    }

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

添加 以添加到最后为例
temp.next = newNode
newNode.pre = temp;

/**
     * 添加
     * @param characterNode
     */
    public void add(CharacterNode characterNode){
        CharacterNode temp = head;
        while (true){
            if (temp.next == null){
                break;
            }
          temp=temp.next;
        }
        temp.next = characterNode;
        characterNode.pre = temp;
    }

修改和单链表一致

/**
     * 修改
     * @param characterNode
     */
    public void update(CharacterNode characterNode){
        if (head.next == null){
            System.out.println("链表为空~~");
            return;
        }
        CharacterNode temp = head.next;
        boolean flag = false;
        while (true){
            if (temp == null){
                break;
            }
            if (temp.id == characterNode.id){
                flag = true;
                break;
            }
            temp= temp.next;
        }
        if (flag){
            temp.name = characterNode.name;
            temp.nickname = characterNode.nickname;
        }else {
            System.out.printf("没有找到编号%d的节点,不能修改\n",characterNode.id);
        }
    }

删除
temp.pre.next = temp.next;
temp.next.pre = temp.pre;

public void del(int id){
        if (head.next == null){
            System.out.println("链表为空~~");
            return;
        }
        CharacterNode temp = head.next;
        boolean flag = false;
        while (true){
            if (temp == null){
                break;
            }
            if (temp.id == id){
                flag= true;
                break;
            }
            temp = temp.next;
        }
        if (flag){
          temp.pre.next = temp.next;
            /**
             * 注意 最后一个节点不能执行下面的语句 ,负责出现空指针
             */
            if (temp.next != null){
                temp.next.pre = temp.pre;
            }
        }else {
            System.out.printf("要删除的 %d 节点不存在\n", id);
        }
    }

猜你喜欢

转载自blog.csdn.net/amazinga/article/details/106872560