双先链表的特点
1.每个元素持有它上下节点的引用
2.可以从前往后遍历,也可以从后往前遍历
代码如下
package com.structure.linked;
/**
* @author zzq
* @Date 2021-07-21 14:39
*/
public class DoubleLinkedListDemo {
public static void main(String[] args) {
DoubleLinkedList list = new DoubleLinkedList();
HeroNodeV2 head1 = new HeroNodeV2(1,"宋江","及时雨");
HeroNodeV2 head2 = new HeroNodeV2(2,"吴用","智多星");
HeroNodeV2 head3 = new HeroNodeV2(3,"卢俊义","玉麒麟");
HeroNodeV2 head4 = new HeroNodeV2(4,"武松","行者");
list.addByOrder(head4);
list.addByOrder(head2);
list.addByOrder(head1);
list.addByOrder(head3);
//list.addByOrder(head3);
list.showList();
// System.out.println("修改后---------");
// System.out.println("删除后---------");
// list.delete(head1);
// list.delete(head2);
// list.delete(head3);
// list.delete(head4);
// HeroNodeV2 newHeroNode = new HeroNodeV2(1,"小卢","玉麒麟``");
//list.update(newHeroNode);
System.out.println("反向打印--------");
list.reversePrint(list.head);
}
}
class DoubleLinkedList {
HeroNodeV2 head = new HeroNodeV2(0,"","");
public void add(HeroNodeV2 heroNodeV2){
HeroNodeV2 temp = head;
while (true){
if(temp.next == null){
break;
}
temp = temp.next;
}
temp.next = heroNodeV2;
heroNodeV2.pre = temp;
}
/**
* 按顺序添加
* @param node
*/
public void addByOrder(HeroNodeV2 node){
HeroNodeV2 temp = head;
boolean flag = false;
while (true){
//到链表的最后了
if(temp.next == null){
break;
}
//位置找到,就在temp的后面
if(temp.next.no > node.no){
break;
}else if(temp.next.no == node.no){
//说明重复了
System.out.println("要插入的数据已经存在----"+node.no);
flag = true;
break;
}
//后移,遍历链表
temp = temp.next;
}
if(flag){
return;
}
//说明node 应该在temp后面
node.next = temp.next;
if(temp.next!=null){
temp.next.pre = node;
}
temp.next = node;
node.pre = temp;
}
/**
* 删除
* @param node
* @return
*/
public boolean delete(HeroNodeV2 node){
HeroNodeV2 temp = head.next;
//head == node 判断
while (true){
if(temp == null){
//说明找到最后一个了
System.out.println("删除失败,未找到待删除的元素----"+node.no);
return false;
}
if(temp.no == node.no){
//找到了,删除该节点 其实就是改变一下引用关系
temp.pre.next = temp.next;
if(temp.next != null){
temp.next.pre = temp.pre;
}
System.out.println("找到待删除的元素----"+node.no);
return true;
}
//继续往后找
temp = temp.next;
}
}
/**
* 修改
* @param node
* @return
*/
public boolean update(HeroNodeV2 node){
//头结点永远不动,只用来遍历
HeroNodeV2 temp = head.next;
//head == node 判断
while (true){
if(temp == null){
//说明找到最后一个了
System.out.println("修改失败,未找到待修改的元素----"+node.no);
return false;
}
if(temp.no == node.no){
//找到了
System.out.println("找到待修改的元素----"+node.no);
temp.name = node.name;
temp.nickName = node.nickName;
return true;
}
//继续往后找
temp = temp.next;
}
}
public void showList(){
if(head.next == null){
System.out.println("链表是空的");
return;
}
//借用一个辅助变量。 head一定不能动,否则链表会出现问题
HeroNodeV2 temp = head.next;
while (true){
if(temp == null){
break;
}
//继续往后找
System.out.println(temp);
temp = temp.next;
}
}
/**
* 反向打印:先找到最后一个,然后往前遍历
* 第二个while可以用递归实现,也可以把元素加到一个新链表
* @param head
*/
public void reversePrint(HeroNodeV2 head){
HeroNodeV2 temp = head;
while (true){
if(temp.next == null){
break;
}
temp = temp.next;
}
while (temp != null) {
if(temp.pre == null){
break;
}
System.out.println(temp);
temp = temp.pre;
}
}
}
class HeroNodeV2 {
HeroNodeV2 pre;
HeroNodeV2 next;
public HeroNodeV2(int no, String name, String nickName) {
this.no = no;
this.name = name;
this.nickName = nickName;
}
/**
* 编号
*/
public int no;
/**
* 姓名
*/
public String name;
/**
* 称号
*/
public String nickName;
@Override
public String toString() {
return "HeroNodeV2{" +
"no=" + no +
", name='" + name + '\'' +
", nickName='" + nickName + '\'' +
'}';
}
}