快速入门无头双链表

简介: 快速入门无头双链表

无头双向单链表的基础功能实现

在单链表的学习中,我们已经掌握了求单链表的长度,是否包含了某一个元素,以及打印单链表,无头双链表的求长度,判断是否包含了某一个元素,打印双链表,都是与单链表的写法一样的,所以这里就不在多做赘述。

头插法

变化前

变化后

代码实现:

 //头插法
        public void addFirst(int data){
        listnode add=new listnode(data);
        if (head==null){//还得考虑链表为空的情况
            head=add;
            last=add;
            return;
        }
        add.next=head;
        head.prve=add;
        head=add;
        }

尾插法

变化前

变化后

代码实现:

 //尾插法
        public void addLast(int data){
            listnode add=new listnode(data);
        if (head==null){//同样需要考虑要是有空列表的情况
            head=add;
            last=add;
            return;
        }
        last.next=add;
        add.prve=last;
        last=add;
        }

删除第一次出现关键字为key的节点

一般情况

出现在头部情况(假设要删除的第一次数据在头部出现):

出现在尾部(假设要删除的数据最后才第一次出现):

对以上情况进行分析之后,我们必须通过遍历来解决,具体实现代码如下:

//删除第一次出现关键字为key的节点
        public void remove(int key){
            if (head==null)return;
        listnode cur=head;
        while (cur!=null){
            if (cur.val==key){
                if (cur==head){
                    cur.next.prve=null;
                    head=head.next;
                }else{
                    cur.prve.next=cur.next;
                    if (cur==last){
                        last=cur.prve;
                    }else{
                        cur.next.prve=cur.prve;
                    }
                }
                return;
            }else{
                cur=cur.next;

            }
        }
        }

但是在这里代码是有缺陷的,因为如果就是一个节点的时候,那么此时代码会报错,我们就需要单独讨论一下,具体代码实现如下:

        public void remove(int key){
            if (head==null)return;
        listnode cur=head;
        while (cur!=null){
            if (cur.val==key){
                if (cur==head){
                    head=head.next;
                    if (head!=null){
                        head.prve=null;
                    }else{
                        last=null;//尾节点要变成null,不然会被一直引用
                    }
                }else{
                    cur.prve.next=cur.next;
                    if (cur==last){
                        last=cur.prve;
                    }else{
                        cur.next.prve=cur.prve;
                    }
                }

            }else{
                cur=cur.next;

            }
        }
        }

删除所有的值为key的节点

这个就需要在删第一次为key的基础上,把return去掉,然后要让cur一直往下走,具体实现代码如下:

//删除所有值为key的节点
        public void removeAllKey(int key){
            if (head==null)return;
            listnode cur=head;
            while (cur!=null){
                if (cur.val==key){
                    if (cur==head){
                        head=head.next;
                        if (head!=null){
                            head.prve=null;
                        }else{
                            last=null;
                        }

                    }else{
                        cur.prve.next=cur.next;
                        if (cur.next!=null){
                            cur.next.prve=cur.prve;
                        }else{
                           last=last.prve;
                        }
                    }
                }
                    cur=cur.next;
            }
        }

任意位置插入

插入前:

插入后

代码实现如下:

 //任意位置插入,第一个数据节点为0号下标
        public listnode search(int index){
            if (index<0||head==null)return null;
            listnode cur=head;
            while (index!=0){
                cur=cur.next;
                if (cur==null){//说明超出链表的长度
                    return null;
                }
                index--;
            }
            return cur;
        }
        public void addIndex(int index,int data){
            listnode listnode=new listnode(data);
            if (index==0){//如果是第一个位置就是头插法
                addFirst(data);
                return;
            }
            if (index==size()){//最后一个位置就是尾插法
                addLast(data);
                return;
            }
            listnode ret=search(index);
            if (ret==null)return;
            ret.prve.next=listnode;
            listnode.next=ret;
            listnode.prve=ret.prve;
            ret.prve=listnode;
        }

清空双链表

代码实现:

       public void clear(){
        while(head!=null){
            listnode cur=head.next;
            head.prve=null;
            head.next=null;
            head=cur;
        }
        last=null;//要把尾节点手动置为null,不然还在被引用
        }


双链表基本功能实现源码

单链表的功能实现

目录
相关文章
|
5天前
|
存储 缓存 算法
链表全景:探索单链表、双向链表与循环链表【实战演练】
链表全景:探索单链表、双向链表与循环链表【实战演练】
34 3
|
5天前
|
存储 C语言
如何实现双向循环链表
如何实现双向循环链表
41 0
|
5天前
无头单链表
无头单链表
28 0
|
5天前
【无头双向链表和链表练习题2】
【无头双向链表和链表练习题2】
25 0
|
9月前
|
存储
单链表————单链表的构建,增删查改功能的实现
单链表————单链表的构建,增删查改功能的实现
|
7月前
|
存储
【数据结构】带头双向循环链表(小白入门必备知识)(上)
【数据结构】带头双向循环链表(小白入门必备知识)(上)
|
7月前
【数据结构】带头双向循环链表(小白入门必备知识)(下)
【数据结构】带头双向循环链表(小白入门必备知识)(下)
|
7月前
|
存储 算法
数据结构入门指南:带头双向循环链表
数据结构入门指南:带头双向循环链表
95 0
|
7月前
|
存储 算法
数据结构与算法之六 双向链表和循环链表
数据结构与算法之六 双向链表和循环链表
26 0
|
9月前
|
存储 算法
【数据结构】庖丁解牛,图文结合带你轻松上手带头循环链表
【数据结构】庖丁解牛,图文结合带你轻松上手带头循环链表
68 0