双向链表
区别
- 单向链表查找的方向只能是从前往后这一方向,而双向链表可以向前也可以向后查找
- 单向链表不能自我删除,只能通过辅助节点,也就是找到待删除节点的前一个节点;而双向链表可以实现自我删除
思路
- 创建节点类和双向链表类
class HeroNode3{
int no;
String name;
String nickName;
HeroNode3 next;
HeroNode3 pre;
public HeroNode3(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 + "]" + "\n";
}
}
class LinkedList{
private HeroNode3 head = new HeroNode3(0,"","");
}
- 获取头节点方法
public HeroNode3 getHead(){
return head;
}
- 添加节点
思路:
- 根据节点编号no进行插入链表,不是直接在链表最后插入节点
- 定义一个辅助节点temp指向head
- 遍历链表,找到编号比待插入节点大的节点temp.next,此时temp是比待插入节点编号小的节点,让
heroNode.next = temp.next; ——>插入节点的next指向temp节点的下一个节点
temp.next = heroNode; ——>让temp节点的next指向插入的节点
temp.next.pre = heroNode; ——>让temp节点下一个节点的pre指向插入节点
heroNode.pre = temp; ——>让插入节点的pre指向temp
public void addByOrder(HeroNode3 heroNode){
HeroNode3 temp = head;
boolean flag = false;
while(true){
if (temp.next == null){
break;
}
if (temp.next.no > heroNode.no){
break;
}else if (temp.next.no == heroNode.no){
flag = true;
break;
}
temp = temp.next;
}
if (flag == true){
System.out.println("该节点编号" + heroNode.no + "在链表中已存在,无法插入数据");
}else{
heroNode.next = temp.next;
temp.next = heroNode;
temp.next.pre = heroNode;
heroNode.pre = temp;
}
}
- 显示链表,遍历(跟单链表的遍历一样,只是双链表可以向前查找)
public void list(){
if (head.next == null){
System.out.println("链表为空!");
return;
}
HeroNode3 temp = head.next;
while(true){
if (temp == null){
break;
}
System.out.println(temp);
temp = temp.next;
}
}
- 修改节点(跟单链表的修改一样,只是修改链表的部分结构,多加一个pre指向域)
public void update(HeroNode3 heroNode){
if (head.next == null){
System.out.println("链表为空!!!");
return;
}
HeroNode3 temp = head.next;
boolean flag = false;
while(true){
if (temp == null){
break;
}
if (temp.no == heroNode.no){
flag = true;
break;
}
temp = temp.next;
}
if (flag){
temp.name = heroNode.name;
temp.nickName = heroNode.nickName;
}else{
System.out.println(heroNode.no + "节点在链表中找不到!!!");
}
}
- 删除节点
思路:
- 定义一个辅助节点temp,到链表中遍历
- 找到待删除节点,让temp指向它,此时temp即是待删除节点
- 进行删除节点temp,分两种情况:一种是该待删除节点是链表最后一个节点;另一种是该节点不是链表最后一个节点
- 针对第一种情况要进行判断,判断temp.next若为空,则不需要执行temp.next.pre = temp.pre;这一语句
- 若temp.next == null,则需执行temp.next.pre = temp.pre;这一语句
public void delete(int no){
if (head.next == null){
System.out.println("链表为空!!!");
return;
}
HeroNode3 temp = head.next;
boolean flag = false;
while(true) {
if (temp == null) {
break;
}
if (temp.no == no){
flag = true;
break;
}
temp = temp.next;
}
if (flag){
temp.pre.next = temp.next;
if (temp.next != null) {
temp.next.pre = temp.pre;
}
}else{
System.out.println(no + "节点在链表中不存在!!!");
}
}
完整代码
package LinkedList;
public class DoubleLinkedList {
public static void main(String[] args) {
HeroNode3 hero1 = new HeroNode3(1, "宋江", "及时雨");
HeroNode3 hero2 = new HeroNode3(2, "卢俊义", "玉麒麟");
HeroNode3 hero3 = new HeroNode3(3, "吴用", "智多星");
HeroNode3 hero4 = new HeroNode3(4, "林冲", "豹子头");
HeroNode3 hero5 = new HeroNode3(5, "武松", "行者");
LinkedList linkedList = new LinkedList();
linkedList.addByOrder(hero1);
linkedList.addByOrder(hero2);
linkedList.addByOrder(hero4);
linkedList.addByOrder(hero5);
linkedList.addByOrder(hero3);
linkedList.list();
HeroNode3 newheroNode = new HeroNode3(2, "小卢卢", "玉麒麟啦");
linkedList.update(newheroNode);
System.out.println("修改后的链表为:");
linkedList.list();
linkedList.delete(5);
System.out.println("删除后的链表为:");
linkedList.list();
}
}
class LinkedList{
private HeroNode3 head = new HeroNode3(0,"","");
public HeroNode3 getHead(){
return head;
}
public void delete(int no){
if (head.next == null){
System.out.println("链表为空!!!");
return;
}
HeroNode3 temp = head.next;
boolean flag = false;
while(true) {
if (temp == null) {
break;
}
if (temp.no == no){
flag = true;
break;
}
temp = temp.next;
}
if (flag){
temp.pre.next = temp.next;
if (temp.next != null) {
temp.next.pre = temp.pre;
}
}else{
System.out.println(no + "节点在链表中不存在!!!");
}
}
public void update(HeroNode3 heroNode){
if (head.next == null){
System.out.println("链表为空!!!");
return;
}
HeroNode3 temp = head.next;
boolean flag = false;
while(true){
if (temp == null){
break;
}
if (temp.no == heroNode.no){
flag = true;
break;
}
temp = temp.next;
}
if (flag){
temp.name = heroNode.name;
temp.nickName = heroNode.nickName;
}else{
System.out.println(heroNode.no + "节点在链表中找不到!!!");
}
}
public void addByOrder(HeroNode3 heroNode){
HeroNode3 temp = head;
boolean flag = false;
while(true){
if (temp.next == null){
break;
}
if (temp.next.no > heroNode.no){
break;
}else if (temp.next.no == heroNode.no){
flag = true;
break;
}
temp = temp.next;
}
if (flag == true){
System.out.println("该节点编号" + heroNode.no + "在链表中已存在,无法插入数据");
}else{
heroNode.next = temp.next;
temp.next = heroNode;
temp.next.pre = heroNode;
heroNode.pre = temp;
}
}
public void list(){
if (head.next == null){
System.out.println("链表为空!");
return;
}
HeroNode3 temp = head.next;
while(true){
if (temp == null){
break;
}
System.out.println(temp);
temp = temp.next;
}
}
}
class HeroNode3{
int no;
String name;
String nickName;
HeroNode3 next;
HeroNode3 pre;
public HeroNode3(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 + "]" + "\n";
}
}