【HuoLe的學習筆記】--雙向連結串列
阿新 • • 發佈:2021-01-13
一、雙向連結串列:
-
每個節點包含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 + '\'' +
'}';
}
}