首页 > 编程语言 >数据结构与算法(四):双向链表

数据结构与算法(四):双向链表

时间:2023-08-06 17:35:33浏览次数:45  
标签:node Node temp 链表 算法 getNextNode 数据结构 节点

基本概念

双向链表概念和单向链表是一致的,区别在于双向链表在单向链表的基础上,指针区域多了一个指向上一个节点的指针。单向链表内容可以参考我的上一篇文章:http://t.csdn.cn/Iu56H。
基本的数据结构如图所示:在这里插入图片描述

链表结构

双向链表结构包含了节点的数据内容和两个指针:指向前一个节点的preNode,和指向下一个节点的nextNode。

@Data
public class Node {
    // 编号
    private Integer no;
    private String name;
    // 后一个节点
    private Node nextNode;
    // 前一个节点
    private Node preNode;
    public Node(Integer no, String name) {
        this.no = no;
        this.name = name;
    }
    @Override
    public String toString() {
        return "Node{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

链表操作

初始化双向链表

private static Node head = new Node(0, "头节点");

打印链表

/**
 * 打印链表
 */
public void showNode() {
    Node temp = head.getNextNode();
    if (temp == null) {
        System.out.println("链表为空");
        return;
    }
    while (true) {
        System.out.println(temp);
        if (temp.getNextNode() == null) {
            break;
        }
        temp = temp.getNextNode();
    }
}

添加节点(无序)

/**
 * 添加节点
 * @param node
 */
public void addNode(Node node) {
    Node temp = head;
    while (true) {
        if (temp.getNextNode() == null) {
            break;
        }
        temp = temp.getNextNode();
    }
    temp.setNextNode(node);
    node.setPreNode(temp);
}

添加节点(按顺序)

当按照编号大小向链表中添加节点时,需要判断当前的节点是否已经是最后一个节点,如果是最后一个节点,咋只需要将原节点的下一个节点指针指向新节点,新节点的上一个节点指针指向原节点即可。
如果新插入的节点位置在链表中部,则需要对原节点的上一个节点和下一个节点都进行相应的赋值处理。

/**
 * 按顺序插入
 * @param node
 */
public void addNodeSort(Node node) {
    Node temp = head;
    while (true) {
        if (temp.getNo() == node.getNo()) {
            System.out.println("节点已存在:" + node.getNo());
            return;
        }
        // 当前节点比新插入的节点大,需要把新节点放到旧节点前面
        if (temp.getNo() > node.getNo()) {
            node.setPreNode(temp.getPreNode());
            temp.getPreNode().setNextNode(node);
            temp.setPreNode(node);
            node.setNextNode(temp);
            return;
        }
        // 最后一个节点
        if (temp.getNextNode() == null) {
            temp.setNextNode(node);
            node.setPreNode(temp);
            return;
        }
        temp = temp.getNextNode();
    }
}

修改节点内容

/**
* 修改节点内容
* @param node
*/
public void updateNode(Node node) {
   Node temp = head;
   boolean isExist = false;
   while (true) {
       // 未找到要修改的节点
       if (temp == null) {
           break;
       }
       if (temp.getNo() == node.getNo()) {
           isExist = true;
           break;
       }
       temp = temp.getNextNode();
   }
   if (isExist) {
       temp.setName(node.getName());
   } else {
       System.out.println("节点未找到");
   }
}

删除节点

如果删除的节点为链表的最后一个节点,将上一个节点的下一节点指针和自己的上一节点指针设置为null即可。如果删除的节点为中间位置,则需要对删除节点的下一个节点值进行相应的操作使其替换掉要删除的节点,这样要删除的节点没有指针指向后会自动被GC回收。

/**
* 删除节点
* @param no
*/
public void deleteNode(Integer no) {
   Node temp = head;
   while (true) {
       if (temp == null) {
           System.out.println("节点未找到");
           return;
       }
       if (temp.getNo() == no) {
           // 删除的是最后一个节点
           if (temp.getNextNode() == null) {
               temp.getPreNode().setNextNode(null);
               temp.setPreNode(null);
               return;
           } else {
               temp.getPreNode().setNextNode(temp.getNextNode());
               temp.getNextNode().setPreNode(temp.getPreNode());
               return;
           }
       }
       temp = temp.getNextNode();
   }
}

标签:node,Node,temp,链表,算法,getNextNode,数据结构,节点
From: https://www.cnblogs.com/wangms821/p/17609619.html

相关文章

  • m基于FFT傅里叶变换的QPSK基带信号频偏估计和补偿算法FPGA实现,包含testbench和matlab
    1.算法仿真效果本系统进行了Vivado2019.2平台的开发,并使用matlab2022a对结果进行星座图的显示:将FPGA的频偏基带QPSK信号和频偏补偿后的QPSK基带信号使用matlab显示星座图,结果如下:2.算法涉及理论知识概要QPSK(QuadraturePhaseShiftKeying)是一种常用的调制方式,它可以在相位和......
  • m基于FFT傅里叶变换的QPSK基带信号频偏估计和补偿算法FPGA实现,包含testbench和matlab
    1.算法仿真效果本系统进行了Vivado2019.2平台的开发,并使用matlab2022a对结果进行星座图的显示:   将FPGA的频偏基带QPSK信号和频偏补偿后的QPSK基带信号使用matlab显示星座图,结果如下:   2.算法涉及理论知识概要       QPSK(QuadraturePhaseShiftKeying)......
  • 基于位相光栅的四波横向剪切干涉法波前检测算法的matlab仿真
    1.算法理论概述      波前检测技术是现代光学中的重要技术之一,可以用于衡量光学系统的成像质量和研究光学系统的异常现象。随着现代光学技术的不断发展,波前检测技术也在不断地发展和完善。其中,基于位相光栅的四波横向剪切干涉法波前检测算法是一种常用的波前检测算法,本文......
  • 最短路径Dijkstra算法--求距离和路径
    1、题目描述求单条路线2、AC代码#include<iostream>#include<cstring>#include<bits/stdc++.h>#defineinf1000000000usingnamespacestd;typedeflonglongll;constintN=105;intn,m,s,t;structnode{ intv;//边终点 intw;//边权 node(intx,inty)......
  • 【JAVA】探索泛型与数据结构:解锁高效编程
    引言在当今信息爆炸的时代,数据结构和算法成为了程序员必备的核心技能。而泛型作为Java语言中的一项强大特性,为数据结构和算法的实现提供了更高效、更安全的方式。本文将深入探讨泛型的概念、使用场景以及结合数据结构的应用,为您打开高效编程之道。第一部分:了解泛型1.1为什么使......
  • 数据结构:堆 heap
    堆分为小顶堆和大顶堆,其本质是一颗完全二叉树,不同点在于:除叶子节点外,小顶堆的每个父节点的key都要比其左右两个子节点的key小;大顶堆的每个父节点的key都要比其左右两个子节点的key大。其中,key是节点的取值,index为节点在树中的索引或者位置。小顶堆/大顶堆的特点在于,其根节点一定......
  • 代码随想录算法训练营第七天|力扣334.反转字符串、力扣541.反转字符串II、剑指offer05
    字符串反转字符串(力扣344.)如果题目关键的部分直接用库函数就可以解决,建议不要使用库函数。毕竟面试官一定不是考察你对库函数的熟悉程度,如果使用python和java的同学更需要注意这一点,因为python、java提供的库函数十分丰富。如果库函数仅仅是解题过程中的一小部分,并且......
  • 力扣-24. 两两交换链表中的节点
     题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 =publicstaticListNodeswapPairs(ListNodehead){if(head==null||head.next==null)returnhead;......
  • 【ACM专项练习#03】打印图形、栈的合法性、链表操作、dp实例
    运营商活动题目描述小明每天的话费是1元,运营商做活动,手机每充值K元就可以获赠1元,一开始小明充值M元,问最多可以用多少天?注意赠送的话费也可以参与到奖励规则中输入输入包括多个测试实例。每个测试实例包括2个整数M,K(2<=k<=M<=1000)。M=0,K=0代表输入结束。输出对于每个测试实......
  • C/C++ 数据结构-直接选择排序
    #include<iostream>#include<Windows.h>usingnamespacestd;voidswap(int*num1,int*num2){inttemp=*num1;*num1=*num2;*num2=temp;}intmain(){intret[]={161,156,170,164,158,180,159,185,172,176};intlen=......