双链表代码实现和讲解

1、什么是链表

  请移步看我前一篇https://www.cnblogs.com/han200113/p/11549338.html

2、双链表和单链表有什么不同?

                                      

  • 双链表相比单链表的date域(节点内容)和next(指向下一个节点)多了一个pre(指向前一个节点)
  • 单链表只能向后向后查找,而双链表由于有节点pre,可实现向前和向后查找
  • 单链表的删除需要借助前一个节点,双链表可改变自身前后节点的指向实现自我删除(详情看代码部分)

3、代码实现讲解

  3.1  添加操作

    循环遍历到链表最后和单链表一样,之后的添加操作除了将当前节点添加到最后,还要把当前节点的pre指向前一个节点,这样才能实现前进后退  

    

 temp.next=personNode;//将当前节点添加到最后一位
 personNode.pre=temp;
  //添加操作
    public  void add(PersonNode personNode){
        //head节点不能动,需要一个节点进行辅助遍历
        PersonNode temp=head;
        while (true){
            if (temp.next==null){ //遍历链表到结尾,跳出循环执行添加操作
                break;
            }
            temp=temp.next;  //辅助节点后移
        }
        temp.next=personNode;//将当前节点添加到最后一位
        personNode.pre=temp;
    }

  3.2 顺序添加

    顺序添加我用的单链表的顺序添加方式也可以,

pnode.pre=temp;

    这句添加与否不影响,希望大神指点

//顺序添加
    public  void addBySort(PersonNode pnode){
        //先顶一个指示
        PersonNode temp=head;
        boolean flag=false;
        while (true){
            if (temp.next==null){
                //System.out.println("add遍历已经结束");
                break;
            }
            if (pnode.no<temp.next.no){

                break;
            }
            else if (pnode.no==temp.next.no){
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if (flag){
            System.out.println("节点已经存在");
        }else {
            pnode.next=temp.next;
            temp.next=pnode;
            pnode.pre=temp;
        }
    }

3.3 修改操作

  和单链表一样,这里不再说了,不理解的可以看下我前一篇单链表的随笔

   //修改
    public void UpdateNode(PersonNode personNode){
        if (head.next==null){
            System.out.println("别修改了,这是空链表");
            return;
        }
        PersonNode temp=head.next;
        boolean flag=false;
        while (true){
            if (temp==null){
                break;
            }
            if (temp.no==personNode.no){
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if (flag){
            temp.no=personNode.no;
            temp.name=personNode.name;
        }else{
            System.out.println("没找到,不改了");
        }
    }

  3.4 删除  (重点)

  先看一下单链表怎么删除的,这里用前一个节点直接指向下下个节点,孤立它,它就被内存回收了

temp.next=temp.next.next;

  我们这里怎么实现的自我删除呢?

        

temp.pre.next=temp.next;//将要删除节点的前节点的next指向该节点的下一个节点
temp.next.pre=temp.pre;//将要删除节点的下一个节点的pre指向该节点的前一个

   还需要注意,如果删除的是最后一个:

      如果还用上面的会出现空指针异常,为什么?

      temp已经是最后一个,temp.next不就是空吗,那temp.next.pre是什么,空的前一个?

      所以这里加了个判断条件if条件

 //删除
    public void  removeNode(int num){
        PersonNode temp=head.next;//如果不用next,每次temp定位就是前一个节点
        boolean flag=false;
        while (true){
            if (temp==null){//遍历结束
                break;
            }
            if (temp.no==num){
                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.println("抱歉,没有找到");
        }
    }

  3.5  列表

   和单链表一样,不在多说

    

    //列表
    public void list(){
        if (head.next==null){
            System.out.println("还找列表?这是个空的");
            return;
        }
        PersonNode temp=head.next;
        while (true){
            if (temp==null){
                System.out.println("好的您已经遍历完了");
                break;
            }
            System.out.println(temp);
            temp=temp.next;
        }
    }

  

原文地址:https://www.cnblogs.com/han200113/p/11556717.html

时间: 2024-10-11 11:08:09

双链表代码实现和讲解的相关文章

实例讲解C++ 双链表基本操作

1.概念 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点.一般我们都构造双向循环链表. 结构图如下所示: 2.基本操作实例 DoubleList.cpp #include "stdafx.h" #include "DoubleList.h" #include <stdio.h> #include <malloc.h>

C语言实现非循环双链表节点的删除(带头结点尾结点)

我在之前一篇博客<C语言实现非循环双链表节点的删除(不带头结点)>中详细讲解了不含头尾节点的双链表中删除一个节点,处理过程还是稍显麻烦.自从我们学习使用头尾节点来处理双链表后,删除过程就非常方便.代码上传至 https://github.com/chenyufeng1991/DeleteNodeDoubleLinkedList_HeadList . 核心代码如下: //删除pos位置的节点 int DeletePosList(Node *pHead,Node *pTail,int pos){

优先双链表

题目: 设有一个双链表,每个结点中除有prior,data和 next这3个域外,还有一个访问频度域 freq,在链表被启用前其值均初始化为0.每当在在链表上进行一次查找操作Locate(L, x)时,令元素值为x的结点中的freq域的值增加1,并使此链表中的结点保持按访问频度域递减的顺序排列,以便使频繁访问的结点总是靠近表头 (1)首先创建一个双链表. (2) 设计一个符合上述要求的Locate(L, x)函数. (3) 具有输出显示访问频度功能. (4) 要求程序通过一个主菜单进行控制,在主

线性表—双链表

1.基础知识 a.双链表结点的结构:其由前序元素地址,数据域,后继元素地址组成. b.双链表结点的连接方法:先声明该结点,可以在内部也可以利用其特性来表明前序结点和后继结点是什么,之后同时还需要说明"其前序结点的后继地址为该结点"和"其后继结点的前序地址为该结点.(本质:双向) 2.循环双链表的实现 线性表接口LList package com.clarck.datastructure.dlinked; /*** 线性表接口LList,描述线性表抽象数据类型,泛型参数T表示数

【c++版数据结构】之双链表的实现(带头结点以及尾节点)

所实现的双链表的结构如下图所示: 双链表的实现,和第一篇文章单链表的实现大致相同点击打开链接 本篇文章在构建节点的同时,初始化构建节点的前驱和后继,具体细节参考下列代码 头文件:DList.h #ifndef DLIST_H_ #define DLIST_H_ typedef enum{FALSE,TRUE}Status; #include<iostream> #include<cassert> using namespace std; template<class Type

循环双链表的简单实现

<span style="font-size:18px;"><strong>//代码为自己编写,可能有问题,欢迎大家留言指正!</strong></span> <span style="font-size:18px;"><strong> </strong></span> #include <iostream> #include <string> u

java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制)

转载请注明出处(请尊重原创!谢谢~): http://blog.csdn.net/javazejian/article/details/53073995 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制) ??这篇是数据结构与算法的第3篇,通过前两篇的介绍,对应顺序表和链表已有

java数据结构与算法之双链表设计与实现

转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/53047590 出自[zejian的博客] 关联文章: 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制) ??上一篇文章分析顺序表和单链表,本篇就接着上篇继续聊链表,在单链表

数据结构之自建算法库——循环双链表

本文针对数据结构基础系列网络课程(2):线性表中第13课时循环链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:cdlinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef CDLINKLIST_H_INCLUDED #define CDLINKLIST_H_INCLUDED //循环双链表基本运算函数 typedef int E