一、双向链表:
-
每个节点包含data域,pre域:指向前一个节点,next域:指向下一个节点
-
双向链表的遍历,添加、修改、删除的操作思路
- 遍历方法和单链表一样,只是可以向前,也可以向后查找
- 添加(默认添加到双向链表的最后)
- 方式一:默认加到最后
- 先找到双向链表的最后这个节点
- temp.next = newNode;
- newNode.pre = temp;
- 方式二:根据排名(id)顺序添加
- 先找到双向链表中可以添加节点的位置
- studentNode.next = temp;//
studentNode.pre = temp.pre;//用新节点取代当前temp的位置 - temp.pre.next = studentNode;//temp.pre的下一个节点指向新节点
- temp.pre = studentNode;//temp位置后移
- java实现:
定义的add函数:
/**
* 向链表中添加节点
* @param studentNode
*/
public void add(DualStudentNode studentNode){
DualStudentNode temp = head;//辅助节点
boolean flag = false;//标志节点是否已经存在
while (true) {
if (temp.id == studentNode.id){
flag = true;//如果链表中已存在该节点,置为true,跳出循环
break;
}
//寻找新加入节点的位置
else if (temp.id > studentNode.id && temp.pre.id < studentNode.id){//找到可以添加的位置,在temp.pre和temp之间
studentNode.next = temp;//
studentNode.pre = temp.pre;//用新节点取代当前temp的位置
temp.pre.next = studentNode;//temp.pre的下一个节点指向新节点
temp.pre = studentNode;//temp位置后移
break;
}
else if (temp.next == null){//遍历到链表最后
temp.next = studentNode;//直接在链表最后添加新节点
studentNode.pre = temp;//新节点的上一个节点为temp
break;
}
temp = temp.next;
}
if (flag){
System.out.printf("已存在节点%s",studentNode);
}
}
建立学生信息:
DualStudentNode student1 = new DualStudentNode(1,"尤雅","female");
DualStudentNode student2 = new DualStudentNode(2,"李彤","female");
DualStudentNode student3 = new DualStudentNode(3,"倪思帆","male");
DualStudentNode student4 = new DualStudentNode(4,"邵浩","male");
DualStudentNode student5 = new DualStudentNode(5,"韦思","male");
DualStudentNode student6 = new DualStudentNode(6,"胡嫚嫚","female");
DualStudentNode student7 = new DualStudentNode(7,"程俊远","male");
DualStudentNode student8 = new DualStudentNode(8,"姚汪鼎","male");
DualStudentNode student9 = new DualStudentNode(9,"朱永琦","male");
DualStudentNode student10 = new DualStudentNode(10,"周霜","female");
DualStudentNode student11 = new DualStudentNode(11,"凌瑾","female");
DualStudentNode student12 = new DualStudentNode(12,"应丰糠","male");
DualStudentNode student13 = new DualStudentNode(13,"庄慧敏","female");
DualStudentNode student14 = new DualStudentNode(14,"于符婷","female");
DualStudentNode student15 = new DualStudentNode(15,"黄淦","male");
DualStudentNode student16 = new DualStudentNode(16,"王祺","male");
乱序添加:
dualLinkedList.add(student13);
dualLinkedList.add(student1);
dualLinkedList.add(student15);
dualLinkedList.add(student7);
dualLinkedList.add(student10);
dualLinkedList.add(student9);
dualLinkedList.add(student5);
dualLinkedList.add(student14);
dualLinkedList.add(student3);
dualLinkedList.add(student12);
dualLinkedList.add(student6);
dualLinkedList.add(student8);
dualLinkedList.add(student11);
dualLinkedList.add(student4);
dualLinkedList.add(student16);
dualLinkedList.add(student2);
dualLinkedList.show();
打印结果:
TestDualLinkedList
StudentNode{id=1, name='尤雅', gender='female'}
StudentNode{id=2, name='李彤', gender='female'}
StudentNode{id=3, name='倪思帆', gender='male'}
StudentNode{id=4, name='邵浩', gender='male'}
StudentNode{id=5, name='韦思', gender='male'}
StudentNode{id=6, name='胡嫚嫚', gender='female'}
StudentNode{id=7, name='程俊远', gender='male'}
StudentNode{id=8, name='姚汪鼎', gender='male'}
StudentNode{id=9, name='朱永琦', gender='male'}
StudentNode{id=10, name='周霜', gender='female'}
StudentNode{id=11, name='凌瑾', gender='female'}
StudentNode{id=12, name='应丰糠', gender='male'}
StudentNode{id=13, name='庄慧敏', gender='female'}
StudentNode{id=14, name='于符婷', gender='female'}
StudentNode{id=15, name='黄淦', gender='male'}
StudentNode{id=16, name='王祺', gender='male'}
Process finished with exit code 0
- 修改和单向链表一样:遍历查找–>修改
- Java实现:
定义的update函数:
/**
* 更新节点信息,根据节点id
* @param studentNode
*/
public void update(DualStudentNode studentNode){
DualStudentNode temp = head.next;//辅助节点
boolean flag = false;//标志是否找到位置
if (temp == null){
System.out.println("链表为空");
}
//遍历链表
while (true){
if (temp == null){
break;
}
if (temp.id == studentNode.id){
flag = true;//找到对应节点,置为true
break;
}
temp = temp.next;
}
if (flag){
//修改信息
temp.name = studentNode.name;
temp.gender = studentNode.gender;
}else {
System.out.println("没有对应节点可修改");
}
}
修改节点:
DualStudentNode student1c = new DualStudentNode(1,"尤雅ya","maybefemale");
dualLinkedList.update(student1c);
dualLinkedList.show();
输出结果:
TestDualLinkedList
原链表所有节点:
StudentNode{id=1, name='尤雅', gender='female'}
StudentNode{id=13, name='庄慧敏', gender='female'}
修改后的链表:
StudentNode{id=1, name='尤雅ya', gender='maybefemale'}
StudentNode{id=13, name='庄慧敏', gender='female'}
Process finished with exit code 0
- 删除
- 因为是双向链表,因此,可以实现自我删除某个节点
- 直接找到要删除的节点,temp
- temp.pre.next = temp.next
- temp.next.pre = temp.pre
- Java实现:
定义的delete函数:
/**
* 删除节点,根据节点id
* @param studentNode
*/
public void delete(DualStudentNode studentNode){
DualStudentNode temp = head.next;
boolean flag = false;//标志是否找到对应节点
if (temp == null){
System.out.println("链表为空");
}
//遍历链表
while (true){
if (temp == null){
break;
}
if (temp.id == studentNode.id){
flag = true;//找到对应节点,置为true
break;
}
temp = temp.next;
}
if (flag) {
//完成删除
temp.pre.next = temp.next;//temp的前一个节点的下一个节点置为temp的下一个节点
temp.next.pre = temp.pre;//temp的下一个节点的上一个节点指向temp的上一个节点
}else {
System.out.println("没有对应节点");
}
}
删除对应节点:
System.out.println("原链表所有节点:");
dualLinkedList.show();
System.out.println("删除后链表所有节点:");
dualLinkedList.delete(student1);
dualLinkedList.show();
输出结果:
原链表所有节点:
StudentNode{id=1, name='尤雅', gender='female'}
StudentNode{id=13, name='庄慧敏', gender='female'}
删除后链表所有节点:
StudentNode{id=13, name='庄慧敏', gender='female'}
整体代码
public class TestDualLinkedList {
public static void main(String[] args){
DualStudentNode student1 = new DualStudentNode(1,"尤雅","female");
DualStudentNode student1c = new DualStudentNode(1,"尤雅ya","maybefemale");
DualStudentNode student2 = new DualStudentNode(2,"李彤","female");
DualStudentNode student3 = new DualStudentNode(3,"倪思帆","male");
DualStudentNode student4 = new DualStudentNode(4,"邵浩","male");
DualStudentNode student5 = new DualStudentNode(5,"韦思","male");
DualStudentNode student6 = new DualStudentNode(6,"胡嫚嫚","female");
DualStudentNode student7 = new DualStudentNode(7,"程俊远","male");
DualStudentNode student8 = new DualStudentNode(8,"姚汪鼎","male");
DualStudentNode student9 = new DualStudentNode(9,"朱永琦","male");
DualStudentNode student10 = new DualStudentNode(10,"周霜","female");
DualStudentNode student11 = new DualStudentNode(11,"凌瑾","female");
DualStudentNode student12 = new DualStudentNode(12,"应丰糠","male");
DualStudentNode student13 = new DualStudentNode(13,"庄慧敏","female");
DualStudentNode student14 = new DualStudentNode(14,"于符婷","female");
DualStudentNode student15 = new DualStudentNode(15,"黄淦","male");
DualStudentNode student16 = new DualStudentNode(16,"王祺","male");
DualLinkedList dualLinkedList = new DualLinkedList();
dualLinkedList.add(student13);
dualLinkedList.add(student1);
dualLinkedList.add(student15);
dualLinkedList.add(student7);
dualLinkedList.add(student10);
dualLinkedList.add(student9);
dualLinkedList.add(student5);
dualLinkedList.add(student14);
dualLinkedList.add(student3);
dualLinkedList.add(student12);
dualLinkedList.add(student6);
dualLinkedList.add(student8);
dualLinkedList.add(student11);
dualLinkedList.add(student4);
dualLinkedList.add(student16);
dualLinkedList.add(student2);
System.out.println("原链表所有节点:");
dualLinkedList.show();
System.out.println("修改后的链表:");
dualLinkedList.update(student1c);
dualLinkedList.show();
System.out.println("删除后链表所有节点:");
dualLinkedList.delete(student1);
dualLinkedList.show();
}
}
class DualLinkedList{
DualStudentNode head = new DualStudentNode(0,"","");
/**
* 向链表中添加节点
* @param studentNode
*/
public void add(DualStudentNode studentNode){
DualStudentNode temp = head;//辅助节点
boolean flag = false;//标志节点是否已经存在
while (true) {
if (temp.id == studentNode.id){
flag = true;//如果链表中已存在该节点,置为true,跳出循环
break;
}
//寻找新加入节点的位置
else if (temp.id > studentNode.id && temp.pre.id < studentNode.id){//找到可以添加的位置,在temp.pre和temp之间
studentNode.next = temp;//
studentNode.pre = temp.pre;//用新节点取代当前temp的位置
temp.pre.next = studentNode;//temp.pre的下一个节点指向新节点
temp.pre = studentNode;//temp位置后移
break;
}
else if (temp.next == null){//遍历到链表最后
temp.next = studentNode;//直接在链表最后添加新节点
studentNode.pre = temp;//新节点的上一个节点为temp
break;
}
temp = temp.next;
}
if (flag){
System.out.printf("已存在节点%s",studentNode);
}
}
/**
* 更新节点信息,根据节点id
* @param studentNode
*/
public void update(DualStudentNode studentNode){
DualStudentNode temp = head.next;//辅助节点
boolean flag = false;//标志是否找到位置
if (temp == null){
System.out.println("链表为空");
}
//遍历链表
while (true){
if (temp == null){
break;
}
if (temp.id == studentNode.id){
flag = true;//找到对应节点,置为true
break;
}
temp = temp.next;
}
if (flag){
//修改信息
temp.name = studentNode.name;
temp.gender = studentNode.gender;
}else {
System.out.println("没有对应节点可修改");
}
}
/**
* 删除节点,根据节点id
* @param studentNode
*/
public void delete(DualStudentNode studentNode){
DualStudentNode temp = head.next;
boolean flag = false;//标志是否找到对应节点
if (temp == null){
System.out.println("链表为空");
}
//遍历链表
while (true){
if (temp == null){
break;
}
if (temp.id == studentNode.id){
flag = true;//找到对应节点,置为true
break;
}
temp = temp.next;
}
if (flag) {
//完成删除
temp.pre.next = temp.next;//temp的前一个节点的下一个节点置为temp的下一个节点
temp.next.pre = temp.pre;//temp的下一个节点的上一个节点指向temp的上一个节点
}else {
System.out.println("没有对应节点");
}
}
/**
* 打印链表中所有节点
*/
public void show(){
//定义辅助变量
DualStudentNode temp = head.next;
if (temp == null){
System.out.println("链表为空");
}
//遍历链表
while (true){
if (temp == null){
break;
}
System.out.println(temp);//打印节点
temp = temp.next;
}
}
}
/**
* 新建DualStudentNode节点类
*/
class DualStudentNode {
int id;//学号
String name;//姓名
String gender;//性别
DualStudentNode pre;//指向前一个节点
DualStudentNode next;//指向下一个节点
//构造函数
public DualStudentNode (int id, String name, String gender) {
this.id = id;
this.name = name;
this.gender = gender;
}
//重写toString()方法
@Override
public String toString() {
return "StudentNode{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
'}';
}
}