链表-双向链表
Posted 奔跑的路奇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链表-双向链表相关的知识,希望对你有一定的参考价值。
链表-双向链表
双向链表
单向链表: 链接.
什么是双链表?
双链表顾名思义,就是链表由单向的链变成了双向链。
使用这种数据结构,我们可以不再拘束于单链表的单向创建于遍历等操作,大大减少了在使用中存在的问题。
双向链表图
在单链表中,有一个指针(该指针是指向下一个节点),而指针域则负责链表之间的“联系”。 而在双向链表中,我们需要有两个指针,一个负责向后连接,一个负责向前连接。
1.1 双向链表的结构
//双向链表的结构
class HeroNode2{
public int no;//编号,删除和修改就是按编号来进行
public String name;//名字
public String nickName;//昵称
public HeroNode2 next; //指向下一个节点 默认null
public HeroNode2 pre;//指向前一个节点,默认null
public HeroNode2(int no,String name,String nickName){
this.no = no;
this.name = name;
this.nickName = nickName;
}
//为了显示方法,重写toString方法
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\\'' +
", nickName='" + nickName +
'}';
}
}
1.2 双向链表的遍历
//先初始化一个 头节点,头节点不动 , 不存放具体的数据
private HeroNode2 head = new HeroNode2(0,"","");
//头节点
public HeroNode2 getHead() {
return head;
}
//遍历双向链表
/**
* 显示链表中的全部数据信息
*/
public void list(){
//先判断链表是否为空
if (head.next == null){
System.out.println("链表为空");
return;
}
//因为头节点,不能动 , 因此我们需要一个辅助遍历来遍历
HeroNode2 temp = head.next;
while (true){
//判断是否是链表的最后
if (temp == null){
break;
}
//输出节点的信息
System.out.println(temp);
//将temp后移,一定要后移,否则会死循环
temp = temp.next;
}
}
1.3 双向链表添加:添加一个节点到双向链表的最后
//双向链表添加:添加一个节点到双向链表的最后
public void add(HeroNode2 heroNode){
//因为 head不动 ,因此我们小一个辅助遍历 temp
HeroNode2 temp = head;
//遍历链表找到最后
while (true){
//当
if (temp.next == null){
break;
}
//如果没有找到最后 , 就将temp后移
temp = temp.next;
}
//当退出while循环时, temp 就指向了链表的最后
temp.next = heroNode;
heroNode.pre = temp; //形成一个双向链表
}
1.4 双向链表修改节点内容
//修改节点内容:双向和单向修改一样
public void update(HeroNode2 newHeroNoe){
//判断是否为空
if (head.next == null){
System.out.println("链表为空");
return;
}
//找到需要修改的节点 , 根据 no 编号
//先定义一个辅助变量
HeroNode2 temp = head.next;
boolean flag = false; //表示没找打到该节点
while (true){
if (temp == null){
break; //到链表的最后,没有找到要修改的节点
}
if (temp.no == newHeroNoe.no){ //找到了
flag = true;
break;
}
temp = temp.next;
}
//根据flag判断是否找到
if (flag){
//找到了,修改
temp.name = newHeroNoe.name;
temp.nickName = newHeroNoe.nickName;
}else {
//没有找到
System.out.println("没有找到该编号的节点,不能修改:"+newHeroNoe.no);
}
}
1.5 双向链表修改节点内容
//从双向链表删除一个节点
//双向链表可以直接找到这个节点,找到后可以自己删除
//
public void delete(int no){
//判断当前链表是否为空
if (head.next == null){
System.out.println("链表为空,无法删除");
return;
}
HeroNode2 temp = head.next;//辅助变量
boolean flag = false;//表示没有找到删除节点的前一个节点
while (true){
if (temp == null){ //没有找到要删除的节点,找到了链表的最后
break;
}
if (temp.no == no){
flag = true; //找到了
break;
}
temp = temp.next;//后移
}
//判断flag
if (flag){
//找到,可以删除
// temp.next = temp.next.next; //但链表的删除方式
temp.pre.next = temp.next; //将
//如果是最后一个节点就不需要执行这句话,否则会有空指针异常
if (temp.next != null) {
temp.next.pre = temp.pre;//将要删除节点的 next和pre 都去掉(但如果是最后一个,最后一个后面没有节点了)
}
}else {
System.out.println("没有找到要删除的节点,该节点不存在:"+no);
}
}
1.6 测试上面所写的方法
public class DoubleLinkedListDemo {
public static void main(String[] args) {
System.out.println("双向链表的测试");
//先创建节点
HeroNode2 heroNode = new HeroNode2(1, "邓超", "天霸");
HeroNode2 heroNode1 = new HeroNode2(2, "陈赫", "动霸");
HeroNode2 heroNode2 = new HeroNode2(3, "鹿晗", "tue");
HeroNode2 heroNode3 = new HeroNode2(4, "杨颖", "baby");
DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
doubleLinkedList.add(heroNode);
doubleLinkedList.add(heroNode1);
doubleLinkedList.add(heroNode2);
doubleLinkedList.add(heroNode3);
doubleLinkedList.list();
System.out.println("修改后的链表");
HeroNode2 heroNode4 = new HeroNode2(4, "ab", "study");
doubleLinkedList.update(heroNode4);
doubleLinkedList.list();
System.out.println("删除节点");
doubleLinkedList.delete(4);
doubleLinkedList.list();
}
}
最后,如果有问题,希望指正,一起进步。
以上是关于链表-双向链表的主要内容,如果未能解决你的问题,请参考以下文章