快速入门无头双链表

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

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

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

头插法

变化前

变化后

代码实现:

 //头插法
        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,不然还在被引用
        }


双链表基本功能实现源码

单链表的功能实现

目录
相关文章
|
8月前
|
存储
顺序表的基本操作(必学)
顺序表的基本操作
102 0
|
3月前
|
C语言
无头链表再封装方式实现 (C语言描述)
如何在C语言中实现无头链表的再封装,包括创建节点和链表、插入和删除操作、查找和打印链表以及销毁链表的函数。
37 0
|
3月前
|
测试技术 C语言
单链表之无头链表(C语言版)
本文详细介绍了使用C语言实现无头单链表的方法,包括节点和链表结构的定义、链表的创建与销毁、节点的插入与删除,以及链表的打印等功能。文章通过具体的代码示例,展示了如何在无头链表中进行头插法、尾插法、自定义位置插入和删除,以及如何清空和销毁链表。
53 0
单链表之无头链表(C语言版)
|
3月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
41 0
|
存储 算法
【数据结构与算法】顺序表增删查改的实现(动态版本+文件操作)附源码
【数据结构与算法】顺序表增删查改的实现(动态版本+文件操作)附源码
95 0
|
8月前
|
存储 缓存 算法
C++链表解析:从基础原理到高级应用,全面掌握链表的使用
C++链表解析:从基础原理到高级应用,全面掌握链表的使用
688 0
|
8月前
|
存储 C语言
链接未来:深入理解链表数据结构(一.c语言实现无头单向非循环链表)
在上一篇文章中,我们探索了顺序表这一基础的数据结构,它提供了一种有序存储数据的方法,使得数据的访 问和操作变得更加高效。想要进一步了解,大家可以移步于上一篇文章:探索顺序表:数据结构中的秩序之美 今天,我们将进一步深入,探讨另一个重要的数据结构——链表 链表和顺序表一样,都属于线性表,也用于存储数据,但其内部结构和操作方式有着明显的不同。通过C语言的具体实现,我们将会更加直观地理解它
139 1
链接未来:深入理解链表数据结构(一.c语言实现无头单向非循环链表)
|
8月前
|
存储 算法 Java
数据结构与算法:栈:如何实现浏览器的前进和后退功能??
数据结构与算法:栈:如何实现浏览器的前进和后退功能??
68 0
|
8月前
无头单链表
无头单链表
48 0
|
8月前
【无头双向链表和链表练习题2】
【无头双向链表和链表练习题2】
39 0