這周的算法作業之一,逆置這步倒不是很難想。
逆置這步就先遞歸到最深層,讓尾巴指向自己的父節點,然後返回到父節點,讓node.next.next指向node就可以實現指向父節點,之後每返回到上層就這樣執行,所以遞歸調用代碼要在node.next.next = node 這行代碼之前執行。
但是昨晚有兩個問題沒想出來,就一直困擾着我。
- 怎麼讓頭結點去指向尾結點?
- 怎麼能讓原來的第一個結點的next爲空?
之後上網查了一下怎麼解決,發現了一個方法。
針對第一個問題,在不斷遞歸的情況下,指針是越走越深的,到尾結點時早就過了頭結點了,怎麼在變化的指針下獲得不變的頭結點呢?發現參數是在遞歸函數中可以始終不發生改變的。
那麼我們將頭結點作爲一個參數,每次遞歸我們不對其進行操作,只傳入,等到最後一次,我們將頭結點next去指向尾結點。
第二個問題,其實是之前少想了一步。之前就想這node.next.next = node,實現了逆置即可。但是對於node.next,並沒有考慮太多。原因是因爲在返回上層函數後,還是會被上述那行代碼所改變。但是當返回到最上層(第一個結點時),並沒有他的父節點了,不可能再往上層返回,所以在執行完子節點指針的逆置操作後,將自己的指針置爲null,就是爲了讓逆置後的尾結點next能爲null而不是指向自己的父結點。
上代碼!!!
Java代碼
結點類Node
/**
* @author 滑技工廠
* @version 1.0
* @ClassName Node
* @Description 結點類
* @date 2020/2/25
*/
public class Node {
Integer data;
Node next;
public Node() {
}
public Node(Integer data, Node next) {
this.data = data;
this.next = next;
}
/*
* @Title reverse
* @Description 逆置單鏈表
* @author 滑技工廠
* @Date 2020/2/25
* @param [node, head]
* @return void
* @throws
*/
public static void reverse(Node node, Node head) {
//如果子節點爲空(到了最後一個結點,尾巴),將頭結點的next指向尾巴,返回上個結點(倒數第二個)
if (node.next == null) {
head.next = node;
return;
}
//一直往下遞歸,直到尾巴
reverse(node.next, head);
//向上返回之後,讓node的子節點的next指向node自己
node.next.next = node;
//這步對於除第一個結點外的其他結點無用,是爲了讓逆置之後的尾結點的next爲null而寫,其他結點的next會因上一步指向自己的父節點
node.next = null;
}
/*
* @Title print
* @Description 打印單鏈表
* @author 滑技工廠
* @Date 2020/2/25
* @param [node]
* @return void
* @throws
*/
public static void print(Node node) {
//node爲空時(此時node=rear.next),不執行
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
/*
* @Title create
* @Description 根據數組創建單鏈表
* @author 滑技工廠
* @Date 2020/2/25
* @param [head, a]
* @return void
* @throws
*/
public static void create(Node head, int a[]) {
Node tmp = head;
for (int i = 0; i < a.length; i++) {
tmp.next = new Node(a[i], null);
tmp = tmp.next;
}
}
}
主類Main
/**
* @ClassName
* @Description 入口類
* @author 滑技工廠
* @date 2020/2/25
* @version 1.0
*/
public class Main {
public static void main(String[] args) {
Node head = new Node();
int[] arr = new int[9];
for (int i = 0; i < arr.length; i++) {
arr[i] = i + 1;
}
Node.create(head, arr);
Node.print(head.next);
System.out.println();
Node.reverse(head.next, head);
Node.print(head.next);
}
}
C++代碼
下面是網上找的一個c++代碼
static void reverse_list(LinkNode *p, LinkNode *&L)
{
if(p->next == NULL) // 以p爲首結點指針的單鏈表只有一個結點時
{
L->next = p; // p結點變爲尾結點
return;
}
reverse_list(p->next, L);
p->next->next = p; // 將結點鏈接在尾結點之後
p->next = NULL; // 尾結點next域置爲NULL
}
————————————————
版權聲明:本文爲CSDN博主「靜能生悟」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/xiezhi123456/article/details/86583167
本篇到此結束。其實是不太想發這篇的,因爲我室友會看我博客饞我代碼(作業),但是還是發出來算了,剛得到的知識拿出來分享總有滿滿的成就感呢!
如果這篇對你有幫助請點擊下方一鍵三連謝謝大家(拿錯臺詞)