1. 程式人生 > >二叉樹中序遍歷非遞迴演算法

二叉樹中序遍歷非遞迴演算法

我們知道,在深度搜索遍歷的過程中,之所以要用遞迴或者是用非遞迴的棧方式,參考二叉樹非遞迴中序遍歷,都是因為其他的方式沒法記錄當前節點的parent,而如果在每個節點的結構裡面加個parent 分量顯然是不現實的,那麼Morris是怎麼解決這一問題的呢?好吧,他用得很巧妙,實際上是用葉子節點的空指標來記錄當前節點的位置,然後一旦遍歷到了葉子節點,發現葉子節點的右指標指向的是當前節點,那麼就認為以當前節點的左子樹已經遍歷完成。Morris 遍歷正是利用了線索二叉樹 的思想。

以inorder為例,初始化當前節點為root,它的遍歷規則如下:

  • 如果當前節點為空,程式退出。
  • 如果當前節點非空,
    • 如果當前節點的左兒子為空,那麼輸出當前節點,當前節點重置為當前節點的右兒子。
    • 如果當前節點的左兒子非空,找到當前節點左子樹的最右葉子節點(此時最右節點的右兒子有兩種情況,一種是指向當前節點,一種是為空,你也許感到奇怪,右節點的右兒子怎麼可能非空,注意,這裡的最右葉子節點只帶的是原樹中的最右葉子節點。),若其最右葉子節點為空,令其指向當前節點,將當前節點重置為其左兒子,若其最右節點指向當前節點,輸出當前節點,將當前節點重置為當前節點的右兒子,並恢復樹結構,即將最右節點的右節點再次設定為NULL
      #include<stdio.h>
      02 #include<stdlib.h>
      03
      04 struct tNode
      05 {
      06 int data;
      07 struct tNode* left;
      08 struct tNode* right;
      09 };
      10
      11 void MorrisTraversal(
      struct tNode *root)
      12 {
      13 struct tNode *current,*pre;
      14

      相關推薦

      ()演算法實現--C語言

      今天繼續二叉樹的學習。 昨天寫了一遍二叉樹的先序遍歷(非遞迴)演算法,今天寫一下二叉樹的二叉樹的中序遍歷(非遞迴)演算法。中序遍歷的非遞迴演算法有兩種,但是個人覺得只要掌握一種就可以了,只要自己的邏輯清晰,會哪一種又有什麼關係呢~ 首先給出今天的二叉樹的示例圖: 程式碼如下:

      演算法

      我們知道,在深度搜索遍歷的過程中,之所以要用遞迴或者是用非遞迴的棧方式,參考二叉樹非遞迴中序遍歷,都是因為其他的方式沒法記錄當前節點的parent,而如果在每個節點的結構裡面加個parent 分量顯然是不現實的,那麼Morris是怎麼解決這一問題的呢?好吧,他用得很巧

      演算法--20181109--實現

      1.二叉樹的中序遍歷 首先看一下遞迴方式的實現方式: class TreeNode: left = None right = None var = 0 def __init__(self, var): self.var = var

      面試題目整理--20181109--實現

      非遞迴實現二叉樹的中序遍歷 首先看一下遞迴方式的實現方式: class TreeNode: left = None right = None var = 0 def __init__(self, var): self.var

      ()演算法實現--C語言

        一直說要寫二叉樹的後序非遞迴遍歷演算法,但是前兩天各種事情,今天終於有時間好好寫一寫二叉樹的後序遍歷演算法。   二叉樹的後序遍歷演算法比先序和中序的遍歷演算法要複雜一些。其出棧條件有兩種情況: 棧頂元素所指向的節點的左子樹和右子樹均為空; 棧頂元素所指向的節點的左子樹

      歸寫法

      sqs nor amp style mage 中序遍歷 遞歸 ack stack 中序遍歷比前序要稍微復雜些,我也先用手寫理出思路 代碼寫的和書上的一比。。。感覺麻煩了好多,但畢竟是自己理的思路不容易忘,所以還是貼自己的 void inOrder_stack(BiTre

      演算法及C語言實現

      二叉樹中序遍歷的實現思想是: 訪問當前節點的左子樹; 訪問根節點; 訪問當前節點的右子樹; 圖 1 二叉樹   以圖  1 為例,採用中序遍歷的思想遍歷該二叉樹的過程為: 訪問該二叉樹的根節點,找到 1; 遍歷節點 1 的左子樹,找到節點 2; 遍歷節點 2 的左子樹,找到節點 4;

      實現(java)

      後序遍歷:雙棧法,和層次遍歷(雙佇列)很相似,唯一區別在於層次遍歷用的 是佇列,後序遍歷用的是棧。 public static void posOrderUnRecur1(Node head){ System.out.print("PosOrder:"); if(head !=

      三種演算法

      1.先序遍歷非遞迴演算法 #define maxsize 100 typedef struct {     Bitree Elem[maxsize];     int top; } SqStack; void PreOrderUnrec(Bitree t) {     SqStack s;     Stack

      演算法及C語言實現

      二叉樹後序遍歷的實現思想是:從根節點出發,依次遍歷各節點的左右子樹,直到當前節點左右子樹遍歷完成後,才訪問該節點元素。 圖 1 二叉樹   如圖 1 中,對此二叉樹進行後序遍歷的操作過程為: 從根節點 1 開始,遍歷該節點的左子樹(以節點 2 為根節點); 遍歷節點 2 的左子樹(以節點 4 為根

      )及C語言實現

      二叉樹先序遍歷的實現思想是: 訪問根節點; 訪問當前節點的左子樹; 若當前節點無左子樹,則訪問當前節點的右子樹; 圖 1 二叉樹   以圖  1 為例,採用先序遍歷的思想遍歷該二叉樹的過程為: 訪問該二叉樹的根節點,找到 1; 訪問節點 1 的左子樹,找到節點 2; 訪問節點 2 的左子

      演算法

             前幾天參加了阿里暑期實習的內推面試,發現自己的資料結構演算法基礎特別薄弱,比如其中一個問題是中序遍歷的遞迴與非遞迴演算法,我平時看資料結構只知道遞迴演算法,非遞迴的演算法直接被問懵逼了,在思考了幾十秒之後想出了用陣列存放每次遍歷節點的父節點,然後用for迴圈遍

      -歸算法

      else postorder nbsp return () pop 入棧 我們 二叉樹 從根結點開始,將所有最左結點全部壓棧,每當一個結點出棧時,都先掃描該結點的右子樹,只有當一個結點的左孩子和右孩子結點均被訪問過了,才能訪問結點自身。 非遞歸算法實現如下:

      按層----實現

      演算法思路 用佇列儲存左右子女的地址。當從佇列中拿出一個節點時,將這個節點的左右子女的地址也放到佇列中 程式碼 #include <stdio.h> #include <stdlib.h> //二叉樹節點的結構 typedef

      typedef struct { BTNode* left; BTNode* right; int data; } BTNode; typedef void (*visit_t)(BTNode* node); void traversal(BTN

      的所有實現

      前言:二叉樹的遍歷形式有很多,比如前序、中序、後序、層序遍歷,在最近的一次面試中,面試官要求手寫層序遍歷程式碼(非遞迴的形式),由此可見遍歷的重要性.本篇部落格我們就來看一下二叉樹的幾種遍歷方式.本篇部落格語言均採用java實現: 目錄: 一:二叉樹簡介 二:前序遍歷 三:中序遍歷 四:後序遍歷 五:層序遍歷

      演算法

      中序遍歷:方法一://中序遍歷 void InOrderWithoutRecursion1(BTNode* root) { //空樹 if (root == NULL) return; //樹非空 BTNode* p = roo

      、後和層實現

      一、中序遍歷 訪問順序:左子樹 -> 結點 -> 右子樹 難點在於訪問左子樹後應該怎麼回到結點本身或者其右子樹呢?這裡利用了堆疊來臨時儲存,需要利用上一個結點時可以pop出來(有種撤回鍵的感覺2333)。 void PreOrderTravel(BinTree BT){

      python 方法

      # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = N

      【LeetCode】Binary Tree Inorder Traversal 以及演算法

        Total Accepted: 16494 Total Submissions: 47494 Given a binary tree, return the inorder traversal of its nodes' values. For example: Giv