package doubleLinkedListDemo;
/**
* 双向链表:他是在一个节点中,内包含一个数据域,一个指向前一个结点pre的指针和后一个节点的指针next
*/
public class DoubleLinkedList {
public static void main(String[] args) {
System.out.println("测试双向链表...");
DoubleList hero = new DoubleList();
HeroNode2 hero1 = new HeroNode2(1,"宋江","及时雨");
HeroNode2 hero2 = new HeroNode2(2,"卢俊义","玉麒麟");
HeroNode2 hero3 = new HeroNode2(3,"吴用","智多星");
HeroNode2 hero4 = new HeroNode2(4,"林冲","豹子头");
hero.addOrderByNo(hero1);
hero.addOrderByNo(hero4);
hero.addOrderByNo(hero2);
hero.addOrderByNo(hero3);
hero.list();
// System.out.println("----------");
// hero.del(2);
// System.out.println("删除指定元素");
// hero.list();
// System.out.println("----------");
// System.out.println("修改指定元素...");
// HeroNode2 hero_4 = new HeroNode2(4,"武松","行者");
// hero.update(hero_4);
// hero.list();
// System.out.println("----------");
// System.out.println("查找编号固定的英雄");
// hero.find(1);
}
}
//双向链表
class DoubleList{
//创建一个头节点(头节点不包含任何数据,只是提供一个指针域指向链表第一个节点,而且不能动)
private HeroNode2 head = new HeroNode2(0,"","");
//1.添加元素
/*
找到链表的末尾,然后在末尾位置添加节点即可
*/
public void add(HeroNode2 heroNode){
if(head.next == null){
head.next = heroNode;
heroNode.pre = head;
return;
}
HeroNode2 temp = head.next;
while(true){
if(temp.next == null){
break;
}
temp = temp.next;
}
temp.next = heroNode;
heroNode.pre = temp;
}
//2.修改元素
public void update(HeroNode2 heroNode){
if(head.next == null){
System.out.println("空链表,无法修改数据...");
return;
}
HeroNode2 cur = head;
boolean flag = false;
while(true){
if(cur.next == null){
break;
}
if(cur.next.no == heroNode.no){
//找到了指定编号的对象,可以修改数据,肯定是修改当前的节点数据
flag = true;
cur = cur.next;
break;
}
cur = cur.next;
}
if(flag){
//找到编号,修改数据
cur.name = heroNode.name;
cur.nickName = heroNode.nickName;
}else{
System.out.println("没有指定编号的数据,修改失败...");
return;
}
}
//查询指定编号的节点对象的数据
/*
分析:
1.只是返回对象的话,打印就好了,而且我重写了toString;
2.只要找到指定no的对象就好了,很简单
*/
public void find(int no){
if(head.next == null){
System.out.println("链表为空,无法查询...");
return;
}
HeroNode2 temp = head.next;
boolean flag = false;
while(true){
if(temp.no == no){
flag = true;
break;
}
if(temp.next == null){
//当前是链表的组后一个数据,还没找到,就打印错误信息
break;
}
temp = temp.next;
}
if(flag){
//输出当前temp
System.out.println(temp);
}else{
System.out.println("未找到指定编号的节点...");
return;
}
}
//删除指定编号的节点对象
/*
分析:
1.由于是单链表,我要是删除指定位置的结点的话,我就需要temp.next.no = no,删除
*/
public void del(int no){
if(head.next == null){
System.out.println("空链表,不能删除...");
return;
}
HeroNode2 cur = head.next;//直接指向头节点,防止删除的元素是第一个
boolean flag = false;//防止找不到元素,打印错误信息
while(true){
//对于双向链表来说,我可以找到自身这个节点,然后删除掉自己
if(cur.no == no){
flag = true;
break;
}
if(cur == null){
//没找到指定编号
break;
}
cur = cur.next;
}
if(flag){
//有bug,如果是最后一个元素就会有异常
if(cur.next != null){
cur.next.pre = cur.pre;
}
cur.pre.next = cur.next;
}else{
System.out.println("没找到指定编号的元素...");
return;
}
}
//显式链表数据
//这个是用来遍历链表的方法
/*
分析:判断temp.next == null,就停止遍历
*/
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.next;
}
}
//按照编号顺序,添加元素
/*
分析:
1.按照顺序查找添加元素的话,就要找到heroNode.no > temp.no && heroNode < temp.next.no;
*/
public void addOrderByNo(HeroNode2 heroNode){
if(head.next == null){
head.next = heroNode;
heroNode.pre = head;
return;
}
HeroNode2 temp = head.next;
boolean flag = false;
while(true){
if(temp.no == heroNode.no){
flag = true;
break;
}
if(temp.next == null){
//找到链表最后也没找到就证明到了最后一个,直接插入就好了
break;
}
if(temp.no < heroNode.no && temp.next.no > heroNode.no){
//找到了
break;
}
temp = temp.next;
}
if(!flag){
if(temp.next == null){
temp.next = heroNode;
heroNode.pre = temp;
}else{
heroNode.next = temp.next;
temp.next.pre = heroNode;
temp.next = heroNode;
heroNode.pre = temp;
}
}else{
System.out.println("插入元素重复,无法插入...");
return;
}
}
}
//创建一个双向链表的节点
class HeroNode2 {
public int no;
public String name;
public String nickName;
public HeroNode2 pre;//指向前一个节点的指针
public HeroNode2 next;//指向后一个节点的指针
//定义一个构造器
public HeroNode2(int no, String name, String nickName) {
this.no = no;
this.name = name;
this.nickName = nickName;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
", nickName='" + nickName + '\'' +
'}';
}
}