遞歸逆置帶頭結點的單鏈表_C/C++&Java

遞歸逆置帶頭結點的單鏈表_C/C++&Java

這周的算法作業之一,逆置這步倒不是很難想。

逆置這步就先遞歸到最深層,讓尾巴指向自己的父節點,然後返回到父節點,讓node.next.next指向node就可以實現指向父節點,之後每返回到上層就這樣執行,所以遞歸調用代碼要在node.next.next = node 這行代碼之前執行。
但是昨晚有兩個問題沒想出來,就一直困擾着我。

  1. 怎麼讓頭結點去指向尾結點?
  2. 怎麼能讓原來的第一個結點的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

本篇到此結束。其實是不太想發這篇的,因爲我室友會看我博客饞我代碼(作業),但是還是發出來算了,剛得到的知識拿出來分享總有滿滿的成就感呢!

如果這篇對你有幫助請點擊下方一鍵三連謝謝大家(拿錯臺詞)

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章