左神算法书籍《程序员代码面试指南》——3_01分别用递归和非递归方式实现二叉树先序、中序和后序遍历【★★★】

【题目】
用递归和非递归方式,分别按照二叉树先序、中序和后序打印所有的节点。我们约定:先序遍历顺序为根、左、右;中序遍历顺序为左、根、右;后序遍历顺序为左、右、根。

  1 #include <iostream>
  2 #include <queue>
  3 #include <vector>
  4 #include <stack>
  5 using namespace std;
  6 struct Node
  7 {
  8     int v;
  9     Node *r, *l;
 10     Node(int a = -1) :v(a), r(nullptr), l(nullptr) {}
 11 };
 12 Node* root = nullptr;
 13 vector<int>res;
 14 void creatTree()
 15 {
 16     root = new Node(1);
 17     root->l = new Node(2);
 18     root->r = new Node(3);
 19     root->l->l = new Node(4);
 20     root->l->r = new Node(5);
 21     root->r->l = new Node(6);
 22     root->r->r = new Node(7);
 23 }
 24 /////////////递归方式///////////////
 25 void preOrder(Node* root)//前序遍历
 26 {
 27     if (root == nullptr)
 28         return;
 29     res.push_back(root->v);
 30     preOrder(root->l);
 31     preOrder(root->r);
 32 }
 33 void inOrder(Node* root)//中序遍历
 34 {
 35     if (root == nullptr)
 36         return;
 37     preOrder(root->l);
 38     res.push_back(root->v);
 39     preOrder(root->r);
 40 }
 41 void lastOrder(Node* root)//后序遍历
 42 {
 43     if (root == nullptr)
 44         return;
 45     lastOrder(root->l);
 46     lastOrder(root->r);
 47     res.push_back(root->v);
 48 }
 49 /////////////非递归方式///////////
 50 void NpreOrder(Node* root)//前序遍历
 51 //1.申请一个新的栈,记为stack。然后将头节点head压入stack中。
 52 //2.从stack中弹出栈顶节点,记为cur,然后打印cur节点的值,再将节点cur的右孩子(不为空的话)先压入stack中,最后将cur的左孩子(不为空的话)压入stack中。
 53 //3.不断重复步骤2,直到stack为空,全部过程结束。
 54 {
 55     if (root == nullptr)
 56         return;
 57     stack<Node*>s;
 58     s.push(root);
 59     while (!s.empty())
 60     {
 61         Node* p = s.top();
 62         s.pop();
 63         res.push_back(p->v);
 64         if (p->r != nullptr)
 65             s.push(p->r);
 66         if (p->l != nullptr)
 67             s.push(p->l);
 68     }
 69 }
 70 
 71 void NinOrder(Node* root)//中序遍历
 72 //1.申请一个新的栈,记为stack。初始时,令变量cur = head。
 73 //2.先把cur节点压入栈中,对以cur节点为头的整棵子树来说,依次把左边界压入栈中,即不停地令cur = cur.left,然后重复步骤2。
 74 //3.不断重复步骤2,直到发现cur为空,此时从stack中弹出一个节点,记为node。
 75 //打印node的值,并且让cur = node.right,然后继续重复步骤2。
 76 //4.当stack为空且cur为空时,整个过程停止。
 77 {
 78     if (root == nullptr)
 79         return;
 80     stack<Node*>s;
 81     Node* p = root;
 82     while (p != nullptr || !s.empty())
 83     {
 84         if (p != nullptr)
 85         {
 86             s.push(p);
 87             p = p->l;
 88         }
 89         else
 90         {
 91             p = s.top();
 92             s.pop();
 93             res.push_back(p->v);
 94             p = p->r;
 95         }
 96     }
 97 }
 98 void NlastOrder1(Node* root)//后序遍历
 99 //先介绍用两个栈实现后序遍历的过程,具体过程如下:
100 //1.申请一个栈,记为sl,然后将头节点head压入sl中。
101 //2.从sl中弹出的节点记为cur,然后依次将cur的左孩子和右孩子压入sl中。
102 //3.在整个过程中,每一个从s1中弹出的节点都放进s2中。
103 //4.不断重复步骤2和步骤3,直到s1为空,过程停止。
104 //5.从s2中依次弹出节点并打印,打印的顺序就是后序遍历的顺序。
105 {
106     if (root == nullptr)
107         return;
108     stack<Node*>s1, s2;
109     s1.push(root);
110     Node* p;
111     while (!s1.empty())
112     {
113         p = s1.top();
114         s1.pop();
115         s2.push(p);
116         if (p->l != nullptr)
117             s1.push(p->l);
118         if (p->r != nullptr)
119             s1.push(p->r);
120     }
121     while (!s2.empty())
122     {
123         p = s2.top();
124         s2.pop();
125         res.push_back(p->v);
126     }
127 }
128 void NlastOrder2(Node* root)//后序遍历
129 //最后介绍只用一个栈实现后序遍历的过程,具体过程如下:
130 //1.申请一个栈,记为stack,将头节点压入stack,同时设置两个变量h和c。在整个流程中,h代表最近一次弹出并打印的节点,c代表stack的栈顶节点,初始时h为头节点,c为null。
131 //2.每次令c等于当前stack的栈顶节点但是不从stack中弹出此时分以下三种情况。
132 //①如果c的左孩子不为null,并且h不等于c的左孩子,也不等于c的右孩子,则把c的左孩子压入stack中。具体解释一下这么做的原因,首先h的意义是最近一次弹出并打印的节点,所以如果h等于c的左孩子或者右孩子,说明c的左子树与右子树已经打印完毕,此时不应该再将c的左孩子放入stack中。否则,说明左子树还没处理过,那么此时将c的左孩子压入stack中。
133 //②如果条件①不成立,并且c的右孩子不为null,h不等于c的右孩子,则把c的右孩子压入stack中。含义是如果h等于c的右孩子,说明c的右子树已经打印完毕,此时不应该再将c的右孩子放入stack中。否则,说明右子树还没处理过,此时将c的右孩子压入stack中。
134 //③如果条件①和条件②都不成立,说明c的左子树和右子树都已经打印完毕,那么从stack中弹出c并打印,然后令h = c。
135 //3.一直重复步骤2,直到stack为空,过程停止。
136 {
137     if (root == nullptr)
138         return;
139     stack<Node*>s;
140     s.push(root);
141     Node* p;//root==h  p==c
142     while (!s.empty())
143     {
144         p = s.top();
145         if (p->l != nullptr && root != p->l && root != p->r)
146             s.push(p->l);
147         else if (p->r != nullptr && root != p->r)
148             s.push(p->r);
149         else
150         {
151             res.push_back(p->v);
152             s.pop();
153             root = p;
154         }
155     }
156 }
157 
158 int main()
159 {
160 
161 }

猜你喜欢

转载自www.cnblogs.com/zzw1024/p/11445161.html
今日推荐