双向链表
双向链表与单向链表的比较
- 单向链表查找方向只能是一个方向,双向链表的可以向前也可以向后
- 单向链表是不可以自我删除的,需要靠辅助节点,并且总要找到待删除节点的前一个结点,双向链表是可以自我删除的
常规操作
双向链表的尾部添加
思路分析
- 找到双向链表的最后节点,同单向链表的遍历方式
- temp.next = new node
- new node.pre = temp;
- 尾节点的后继指针后指,新节点的前继指针前指
代码实现
我的代码:
package linkedlist;
public class DoubleLinkedKist {
public static void main(String[] args) {
DLL d1 = new DLL();
Hero h1 = new Hero(1,"旁边的","打字砸键盘");
Hero h2 = new Hero(2,"peach","canyouhear");
Hero h3 = new Hero(3,"fulck","bi1qusi1");
Hero h4 = new Hero(4,"haona1","zhenwuyua");
d1.add(h1);
d1.add(h2);
d1.add(h3);
d1.add(h4);
d1.show();
}
}
class DLL{
private Hero head = new Hero(1,"","");
public void add(Hero hero){
Hero temp = head;
while (true){
if(temp.next == null){
break;
}
//在这里注意,尾节点的判定,不是本身是空的
//而是看他的next是否为空,show方法输出的时候可以直接判定本身是否为空
temp = temp.next;
}
temp.next = hero;
hero.pre = temp;
}
public void show(){
if(head.next == null){
System.out.println("链表为空");
}
Hero temp = head.next;
while (temp != null){
System.out.println(temp);
temp = temp.next;
}
}
}
class Hero{
private int no;
private String name;
private String nickName;
Hero pre;
Hero next;
@Override
public String toString() {
return "Hero{" +
"no=" + no +
", name='" + name + '\'' +
", nickName='" + nickName + '\'' +
'}';
}
public Hero(int no, String name, String nickName) {
this.no = no;
this.name = name;
this.nickName = nickName;
}
}
双向链表的删除
思路分析
- 自我删除,无需找到待删除结点的前一个结点
- 直接找到待删除结点
- temp.pre.next = temp.next
- temp.next.pre = temp.pre
代码实现:
我的代码:
public int getLength(){
int size = 0;
Hero temp = head.next;
while (temp != null){
size ++;
temp = temp.next;
}
return size;
}
public void delete(int no){
Hero temp = head;
if(temp.next == null){
System.out.println("链表为空");
}
int size = getLength();
if(no <= 0 || no > size){
System.out.println("输入的索引无效");
}
boolean isFlag = false;
while (true){
if(temp == null){
isFlag = true;
break;
}
if(temp.no == no){
break;
}
temp = temp.next;
}
if(isFlag){
System.out.println("你要删除的节点不存在");
}else{
temp.pre.next = temp.next;
temp.next.pre = temp.pre;
}
}
修改:
if(isFlag){
System.out.println("你要删除的节点不存在");
}else{
temp.pre.next = temp.next;
temp.next.pre = temp.pre;
}
如果删除的是最后一个节点,会出现空指针异常,所以应该加一个判断语句,判断是否为最后一个节点
if(isFlag){
System.out.println("你要删除的节点不存在");
}else{
temp.pre.next = temp.next;
if(temp.next != null){
temp.next.pre = temp.pre;
}
}
总结
- 作为链表本身就带有的方法,我们在调用其本身的方法时,没必要在传入头指针
- 链表操作自身,作为已知元素,也是没必要判定是否为空链表的
- 代码太过冗余和麻烦
- 没码一个代码块,想清楚每一个代码块的要素,while循环语句,初始条件,循环体,迭代条件,终止条件,每一次都会漏
来源:CSDN
作者:~梦醒~
链接:https://blog.csdn.net/Blackoutdragon/article/details/103804564