算法9---二叉樹的遍歷不用棧和遞歸

二叉樹的遍歷不用棧和遞歸

轉自:ACM之家?http://www.acmerblog.com/inorder-tree-traversal-without-recursion-and-without-stack-5988.html
我們知道,在深度搜索遍歷的過程中,之所以要用遞歸或者是用非遞歸的棧方式,參考二叉樹非遞歸中序遍歷,都是因為其他的方式沒法記錄當前節點的parent,而如果在每個節點的結構里面加個parent 分量顯然是不現實的,那么Morris是怎么解決這一問題的呢?好吧,他用得很巧妙,實際上是用葉子節點的空指針來記錄當前節點的位置,然后一旦遍歷到了葉子節點,發現葉子節點的右指針指向的是當前節點,那么就認為以當前節點的左子樹已經遍歷完成。Morris 遍歷正是利用了線索二叉樹?的思想。
以inorder為例,初始化當前節點為root,它的遍歷規則如下:
- 如果當前節點為空,程序退出。
- 如果當前節點非空,
- 如果當前節點的左兒子為空,那么輸出當前節點,當前節點重置為當前節點的右兒子。
- 如果當前節點的左兒子非空,找到當前節點左子樹的最右葉子節點(此時最右節點的右兒子有兩種情況,一種是指向當前節點,一種是為空,你也許感到奇怪,右節點的右兒子怎么可能非空,注意,這里的最右葉子節點只帶的是原樹中的最右葉子節點。),若其最右葉子節點為空,令其指向當前節點,將當前節點重置為其左兒子,若其最右節點指向當前節點,輸出當前節點,將當前節點重置為當前節點的右兒子,并恢復樹結構,即將最右節點的右節點再次設置為NULL
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 
 4 struct tNode
 5 {
 6    int data;
 7    struct tNode* left;
 8    struct tNode* right;
 9 };
10 
11 void MorrisTraversal(struct tNode *root)
12 {
13   struct tNode *current,*pre;
14 
15   if(root == NULL)
16      return; 
17 
18   current = root;
19   while(current != NULL)
20   {                 
21     if(current->left == NULL)
22     {
23       printf(" %d ", current->data);
24       current = current->right;      
25     }    
26     else
27     {
28       /* 找到current的前驅節點 */
29       pre = current->left;
30       while(pre->right != NULL && pre->right != current)
31         pre = pre->right;
32 
33       /* 將current節點作為其前驅節點的右孩子 */
34       if(pre->right == NULL)
35       {
36         pre->right = current;
37         current = current->left;
38       }
39 
40       /* 恢復樹的原有結構,更改right 指針 */   
41       else 
42       {
43         pre->right = NULL;
44         printf(" %d ",current->data);
45         current = current->right;      
46       } /* End of if condition pre->right == NULL */
47     } /* End of if condition current->left == NULL*/
48   } /* End of while */
49 }
50 
51 struct tNode* newtNode(int data)
52 {
53   struct tNode* tNode = (struct tNode*)
54                        malloc(sizeof(struct tNode));
55   tNode->data = data;
56   tNode->left = NULL;
57   tNode->right = NULL;
58 
59   return(tNode);
60 }
61 
62 /* 測試*/
63 int main()
64 {
65 
66   /* 構建樹結構如下:
67             1
68           /   \
69         2      3
70       /  \
71     4     5
72   */
73   struct tNode *root = newtNode(1);
74   root->left        = newtNode(2);
75   root->right       = newtNode(3);
76   root->left->left  = newtNode(4);
77   root->left->right = newtNode(5); 
78 
79   MorrisTraversal(root);
80    return 0;
81 }

?

轉載于:https://www.cnblogs.com/tao-alex/p/5894348.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/260513.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260513.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260513.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python調用攝像頭人臉識別代碼_利用face_recognition,dlib與OpenCV調用攝像頭進行人臉識別...

用已經搭建好 face_recognition&#xff0c;dlib 環境來進行人臉識別 未搭建好環境請參考&#xff1a; 使用opencv 調用攝像頭 import face_recognition import cv2 video_capture cv2.videocapture(0) # videocapture打開攝像頭&#xff0c;0為筆記本內置攝像頭&#xff0c;1…

python列表批量 修改_python實現多進程按序號批量修改文件名的方法示例

本文實例講述了python實現多進程按序號批量修改文件名的方法。分享給大家供大家參考&#xff0c;具體如下&#xff1a;說明文件名命名方式如圖&#xff0c;是數字序號開頭&#xff0c;但是中間有些文件刪掉了&#xff0c;序號不連續&#xff0c;這里將序號連續起來&#xff0c;…

Struts1 tag

標簽庫&#xff1a; a) struts框架下的struts標簽庫 b) sun jstl c標簽庫 作用: 1) jsp 和 java代碼分離 -- 自定義標簽 用標簽來替代Java的代碼 2) struts標簽 能夠和struts-config.xml actionForm等特有的對象進行交互 stru…

“multiprocessing\spawn.py”, line 105, in spawn_main錯誤與解決方法

記錄一個不知名的錯誤錯誤解決方法OS&#xff1a; Windows 10 錯誤非常的長&#xff0c;以至于&#xff0c;我也沒有什么耐心去看&#xff0c;看了前面幾行&#xff0c;應該是多線程引起的。下面太長&#xff0c;可以選擇不看。 錯誤 Traceback (most recent call last): Trac…

hpunix下11gRac的安裝

一.檢查環境 1.操作系統版本# uname -a 2.補丁包三大補丁包#swlist -l bundle|grep QPKAPPS#swlist -l bundle|grep QPKBASE#swlist -l bundle|grep HWEnable11i #swlist -l patch -a supersedes|grep PHKL_XXXXX檢查是否已有或是已被替代For HP-UX 11i V3 (11.31): PHCO_40381…

【轉】徹底搞清計算結構體大小和數據對齊原則

數據對齊: 許多計算機系統對基本數據類型合法地址做出了一些限制&#xff0c;要求某種類型對象的地址必須是某個值K(通常是2&#xff0c;4或8)的倍數。這種對齊限制簡化了形成處理器和存儲器系統之間的接口的硬件設計。例如&#xff0c;假設一個處理器總是從存儲器中取出8個字節…

python里pip是什么意思_python使用pip的方法是什么

python使用pip的方法是什么 發布時間&#xff1a;2020-08-25 11:51:08 來源&#xff1a;億速云 閱讀&#xff1a;104 作者&#xff1a;小新 小編給大家分享一下python使用pip的方法是什么&#xff0c;相信大部分人都還不怎么了解&#xff0c;因此分享這篇文章給大家參考一下&am…

Pytorch 學習率衰減 之 余弦退火與余弦warmup 自定義學習率衰減scheduler

學習率衰減&#xff0c;通常我們英文也叫做scheduler。本文學習率衰減自定義&#xff0c;通過2種方法實現自定義&#xff0c;一是利用lambda&#xff0c;另外一個是繼承pytorch的lr_scheduler import math import matplotlib.pyplot as plt import numpy as np import torch i…

c++ 字符串賦給另一個_7.2 C++字符串處理函數

點擊上方“C語言入門到精通”&#xff0c;選擇置頂第一時間關注程序猿身邊的故事作者閆小林白天搬磚&#xff0c;晚上做夢。我有故事&#xff0c;你有酒么&#xff1f;C字符串處理函數C語言和C提供了一些字符串函數&#xff0c;使得用戶能很方便地對字符串進行處理。這些是放在…

如何檢測遠程主機上的某個端口是否開啟

有時候我們要測試遠程主機上的某個端口是否開啟&#xff0c;無需使用太復雜的工作&#xff0c;windows下就自帶了工具&#xff0c;那就是telnet。怎么檢測呢&#xff0c;按下面的步驟&#xff1a; 1、安裝telnet。我的win7下就沒有telnet&#xff0c;在cmd下輸入telnet提示沒有…

Windows10 + WSL (Ubuntu) + Anaconda + vscode 手把手配置python運行環境(含虛擬環境)

配置WSL windows桌面下&#xff0c;按下面順序可以找到 "啟動或關閉windows功能” &#xff0c; 開始 -> 設置 -> 應用 -> 應用和功能 -> 可選功能 -> 相關設置下 更多Windows功能&#xff08;滾動鼠標到底部&#xff09;點擊后&#xff0c;會彈出 啟動或…

Inline函數使用注意事項

Inline函數使用注意事項 1.在一個文件中定義的inline函數不能再另一個文件中使用 2.inline函數應簡潔&#xff0c;只有少數幾個語句。 3.在inline函數中不能有循環&#xff0c;if&#xff0c;switch語句。 4.inline函數要在調用和聲明前定義&#xff01;&#xff01;&#xff0…

2019編譯ffepeg vs_如何在windows10下使用vs2017編譯最新版本的FFmpeg和ffplay

該文章描述了如何在windows10 64位系統下面編譯出FFmpeg的庫及其自帶的ffplay播放器&#xff0c;而且全部采用最新的版本&#xff0c;這樣我們可以在vs2017的ide下調試ffplay&#xff0c;能使我們更容易學習FFmpeg的架構以及音視頻播放器的原理。步驟&#xff1a;1.安裝vs2017在…

訓練集山準確率高測試集上準確率很低_推薦算法改版前的AB測試

編輯導語&#xff1a;所謂推薦算法就是利用用戶的一些行為&#xff0c;通過一些數學算法&#xff0c;推測出用戶可能喜歡的東西&#xff1b;如今很多軟件都有這樣的操作&#xff0c;對于此系統的設計也會進行測試&#xff1b;本文作者分享了關于推薦算法改版前的AB測試&#xf…

C#實現漸變顏色的Windows窗體控件

C#實現漸變顏色的Windows窗體控件! 1,定義一個BaseFormGradient,繼承于System.Windows.Forms.Form2,定義三個變量: privateColor _Color1 Color.Gainsboro; privateColor _Color2 Color.White; privatefloat_ColorAngle 0f;3,重載OnPaintBackground方法 protecte…

ios7開發學習筆記-包括c oc 和ios介紹

請查看我的新浪資料分享 http://iask.sina.com.cn/u/2430843520 轉載于:https://www.cnblogs.com/langtianya/p/3708298.html

Windows下 jupyter notebook 運行multiprocessing 報錯的問題與解決方法

文章目錄測試用的代碼錯誤解決方法測試用的代碼 下面每一個對應一個jupyter notebook的單元格 import time from multiprocessing import Process, Queuedef generator():c 0while True:time.sleep(1.0) # read somethingyield cc 1%%timeds generator() for i in range(3…

如何將javaweb項目部署到linux下

以下是對將javaweb項目部署到linux下的方法進行了詳細的分析介紹一般都在windows下開發的現在部署到linux下將項目達成war包(用eclipse項目右鍵>Export>選擇war file)將tomcat(用winSCP當然你也可以用secureCRT用securCRT需要建立sftp(即上傳文件的目錄)用put tomcat命令…

vc mysql_vc6.0連接mysql數據庫

一、MySQL的安裝Mysql的安裝去官網下載就可以。。。最新的是5.7版本。。二、VC6.0的設置(1)打開VC6.中選0 工具欄Tools菜單下的Options選項&#xff0c;在Directories的標簽頁中右邊的“Show directories for:”下拉列表中“Includefiles”&#xff0c;然后在中間列表框中添加你…

python class用法_python原類、類的創建過程與方法

【小宅按】今天為大家介紹一下python中與class 相關的知識……獲取對象的類名python是一門面向對象的語言&#xff0c;對于一切接對象的python來說&#xff0c;咱們有必要深入的學習與了解一些知識首先大家都知道&#xff0c;要獲取一個對象所對應的類&#xff0c;需要使用clas…