国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

遞歸調用的理解

2019-11-11 03:44:47
字體:
來源:轉載
供稿:網友
關于遞歸調用的理解問題

前幾天做題的時候,發現《數據結構高分筆記》第一章有這樣一個思考題,對理解遞歸調用幫助很大,題目如下:

題目:逆序輸出單鏈表的數據域,要求 指針l指向鏈表首元結點,且只用l一個指針(一)分析:在單鏈表的情況下,要逆序輸出結點數據只用一個指針,除了用遞歸調用,好象沒有別的方法了。關鍵在于,如何設計遞歸調用?            遞歸調用屬于分治法的一種思想,一個包含直接或者間接調用自身函數的語句的函數被稱為遞歸函數,但不是所有的調用自身都是遞歸,必須滿足以下條件:          (1)在每一次調用自身時,必須是(在某種意義上)更接近于解;          (2)必須有一個終止 處理或者計算 的準則;設計的算法如下:————————————————————————————————————void reversePRint(LNode *l)                                            //逆序輸出鏈表{if (l->next!= NULL){reversePrint(l->next);}cout << l->data<<" -- ";}————————————————————————————————————            我們假設從首元結點到尾元結點共有9個結點,指針l指向首元結點,當執行到if語句時,很明顯” l->next!= NULL “成立,于是執行“ reversePrint(l->next); ”進入遞歸第二層,第二層循環執行到if語句后同樣” l->next!= NULL “成立,于是進入到遞歸第三層……值得說明的是“ reversePrint(l->next); ”語句中,( )中必須寫成”( l->next )“,如果寫成(l),便會進入死循環,違背了上面條件(1)。而” l->next!= NULL “就是終止處理的準則,也就是上面的條件(2);                        當進入遞歸第九層以后,” l->next!= NULL “不成立,于是直接執行" cout << l->data<<" -- "; "輸出結點9的數據,第九層遞歸執行結束。但第九層遞歸執行結束以后,第八層遞歸if語句執行完畢,也進入" cout << l->data<<" -- "; "語句輸出結點9的數據域,第八層遞歸執行結束。以此類推,7、6、5、4、3、2、1依次執行" cout << l->data<<" -- "; "語句,于是整個鏈表就被逆序輸出,而且從頭到尾l指針所指的始終是首元結點(每一層的l可以看成每一層自己定義的指針,只不過名字相同,這點很重要)。因此,使用指針l,如果用for循環輸出則為正序,使用遞歸就可以達到逆序輸出的目的。        另外值得一提的是" cout << l->data<<" -- "; "語句的位置因該放在函數哪里,也是一個值得深思的問題。 (二)關于遞歸調用的時間復雜度問題        如上九個結點,九層循環的時間復雜度為9,也就是說這個算法時間復雜度為O(n)。初學者可能會懷疑時間復雜度為n次方,但是仔細比較就會發現,遞歸和循環的時間復雜度很類似。遞歸九層逆序輸出,時間復雜度為9;for(i=1;i<=9;i++){……}循環順序輸出9次,時間復雜度也是9。        因此,靈活的使用遞歸和循環,可以解決線性表的各種順序以及逆序問題!完整的代碼如下(VS2013編譯環境):————————————————————————————————————//  逆序打印單鏈表的數據    指針l指向鏈表開始  要求只用l一個指針/*分析: 采用遞歸   printNode {if(l->next!=NULL)printNode(l->next);cout<<l->data;}         很神奇的想法!對理解遞歸有很大幫助!!!*/#include "stdafx.h"#include <iostream>#include "stdlib.h"using namespace std;static int length = 9;typedef struct LNode{                                                            //結點的定義int data;struct LNode *next;}LNode;LNode *createLink( )//創立鏈表 {//創立頭結點LNode *head;head = (LNode *)malloc(sizeof(LNode));head->data = 0; head->next = NULL;//創立剩下的結點LNode *newNode, *p = head;for (int i = 1; i <= length; i++) {newNode = (LNode *)malloc(sizeof(LNode));newNode->data = i; newNode->next = NULL;p->next = newNode;p = p->next;}return head;}void printLink(LNode *head)//輸出鏈表 {cout << "當前鏈表為:";LNode *temp = head->next;do{cout << temp->data << " -- ";temp = temp->next;} while (temp->next!=NULL);cout << temp->data;cout << endl;}void reversePrint(LNode *l)                                            //逆序輸出鏈表{if (l->next!= NULL){reversePrint(l->next);}cout << l->data<<" -- ";}int _tmain(int argc, _TCHAR* argv[]){LNode *head = createLink();printLink(head);cout << "逆序鏈表為:";reversePrint(head->next);        cout << endl;return 0;}————————————————————————————————————

輸出結果如下: 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 象州县| 巴塘县| 苗栗县| 德惠市| 镇康县| 廉江市| 孙吴县| 阿尔山市| 永登县| 卢龙县| 铜陵市| 灵山县| 米林县| 弥勒县| 泾川县| 绥阳县| 嘉祥县| 五指山市| 界首市| 顺平县| 柳林县| 广汉市| 淳安县| 南投县| 林口县| 南江县| 阳原县| 铜陵市| 如皋市| 博兴县| 临湘市| 开阳县| 聂荣县| 沾益县| 桦川县| 桑日县| 板桥市| 万山特区| 安新县| 克拉玛依市| 滁州市|