二叉树的先序/中序/后序/层次遍历

【简介】

树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用。

二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用作二叉查找树和二叉堆或是二叉排序树。二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2的 i -1次方个结点;深度为k的二叉树至多有2^(k) -1个结点;对任何一棵二叉树T,如果其终端结点数(即叶子结点数)为n0,度为2的结点数为n2,则n0 = n2 + 1。

二叉树的链式存储结构是一类重要的数据结构,其形式定义如下:

[cpp] view plaincopy

  1. //二叉树结点
  2. typedef struct BiTNode{
  3. //数据
  4. char data;
  5. //左右孩子指针
  6. struct BiTNode *lchild,*rchild;
  7. }BiTNode,*BiTree;

或者

[cpp] view plaincopy

  1. // 二叉树节点结构
  2. struct TreeNode{
  3. int val;
  4. TreeNode *left;
  5. TreeNode *right;
  6. TreeNode(int x):val(x),left(nullptr),right(nullptr){}
  7. };

【二叉树的创建】

通过读入一个字符串,建立二叉树的算法如下:

[cpp] view plaincopy

  1. //按先序序列创建二叉树
  2. int CreateBiTree(BiTree &T){
  3. char data;
  4. //按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树
  5. scanf("%c",&data);
  6. if(data == ‘#‘){
  7. T = NULL;
  8. }
  9. else{
  10. T = (BiTree)malloc(sizeof(BiTNode));
  11. //生成根结点
  12. T->data = data;
  13. //构造左子树
  14. CreateBiTree(T->lchild);
  15. //构造右子树
  16. CreateBiTree(T->rchild);
  17. }
  18. return 0;
  19. }

或者

[cpp] view plaincopy

  1. // 1.创建二叉树
  2. void CreateTree(TreeNode* &root){
  3. int val;
  4. //按先序次序输入二叉树中结点的值,‘-1’表示空树
  5. cin>>val;
  6. // 空节点
  7. if(val == -1){
  8. root = nullptr;
  9. return;
  10. }//if
  11. root = new TreeNode(val);
  12. //构造左子树
  13. CreateTree(root->left);
  14. //构造右子树
  15. CreateTree(root->right);
  16. }

层次建立二叉树:

[cpp] view plaincopy

  1. struct TreeNode {
  2. int val;
  3. TreeNode *left;
  4. TreeNode *right;
  5. TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  6. };

[cpp] view plaincopy

  1. // 创建二叉树
  2. TreeNode* CreateTreeByLevel(vector<char> num){
  3. int len = num.size();
  4. if(len == 0){
  5. return NULL;
  6. }//if
  7. queue<TreeNode*> queue;
  8. int index = 0;
  9. // 创建根节点
  10. TreeNode *root = new TreeNode(num[index++]);
  11. // 入队列
  12. queue.push(root);
  13. TreeNode *p = NULL;
  14. while(!queue.empty() && index < len){
  15. // 出队列
  16. p = queue.front();
  17. queue.pop();
  18. // 左节点
  19. if(index < len && num[index] != -1){
  20. // 如果不空创建一个节点
  21. TreeNode *leftNode = new TreeNode(num[index]);
  22. p->left = leftNode;
  23. queue.push(leftNode);
  24. }
  25. index++;
  26. // 右节点
  27. if(index < len && num[index] != -1){
  28. // 如果不空创建一个节点
  29. TreeNode *rightNode = new TreeNode(num[index]);
  30. p->right = rightNode;
  31. queue.push(rightNode);
  32. }
  33. index++;
  34. }//while
  35. return root;
  36. }

-1代表NULL

创建如上二叉树输入:

15 11 20 8 14 -1 -1 -1 -1 13 -1

【二叉树的遍历】

遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,树的遍历实质上是将二叉树的各个结点转换成为一个线性序列来表示。

【递归算法】

[cpp] view plaincopy

  1. //输出
  2. void Visit(BiTree T){
  3. if(T->data != ‘#‘){
  4. printf("%c ",T->data);
  5. }
  6. }
  7. //先序遍历
  8. void PreOrder(BiTree T){
  9. if(T != NULL){
  10. //访问根节点
  11. Visit(T);
  12. //访问左子结点
  13. PreOrder(T->lchild);
  14. //访问右子结点
  15. PreOrder(T->rchild);
  16. }
  17. }
  18. //中序遍历
  19. void InOrder(BiTree T){
  20. if(T != NULL){
  21. //访问左子结点
  22. InOrder(T->lchild);
  23. //访问根节点
  24. Visit(T);
  25. //访问右子结点
  26. InOrder(T->rchild);
  27. }
  28. }
  29. //后序遍历
  30. void PostOrder(BiTree T){
  31. if(T != NULL){
  32. //访问左子结点
  33. PostOrder(T->lchild);
  34. //访问右子结点
  35. PostOrder(T->rchild);
  36. //访问根节点
  37. Visit(T);
  38. }
  39. }
【非递归算法】
【先序遍历】

【思路】:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。

[cpp] view plaincopy

  1. /* 先序遍历(非递归)
  2. 思路:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
  3. */
  4. void PreOrder2(BiTree T){
  5. stack<BiTree> stack;
  6. //p是遍历指针
  7. BiTree p = T;
  8. //栈不空或者p不空时循环
  9. while(p || !stack.empty()){
  10. if(p != NULL){
  11. //存入栈中
  12. stack.push(p);
  13. //访问根节点
  14. printf("%c ",p->data);
  15. //遍历左子树
  16. p = p->lchild;
  17. }
  18. else{
  19. //退栈
  20. p = stack.top();
  21. stack.pop();
  22. //访问右子树
  23. p = p->rchild;
  24. }
  25. }//while
  26. }

[cpp] view plaincopy

  1. // 先序遍历
  2. void PreOrder(TreeNode* root){
  3. if(root == NULL){
  4. return;
  5. }
  6. stack<TreeNode*> stack;
  7. stack.push(root);
  8. TreeNode *p = NULL;
  9. while(!stack.empty()){
  10. p = stack.top();
  11. stack.pop();
  12. cout<<p->val<<endl;
  13. // 右子节点不空压入栈中
  14. if(p->right){
  15. stack.push(p->right);
  16. }
  17. // 左子节点不空压入栈中
  18. if(p->left){
  19. stack.push(p->left);
  20. }
  21. }//while
  22. }
【中序遍历】

【思路】:T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
         先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。

[cpp] view plaincopy

  1. void InOrder2(BiTree T){
  2. stack<BiTree> stack;
  3. //p是遍历指针
  4. BiTree p = T;
  5. //栈不空或者p不空时循环
  6. while(p || !stack.empty()){
  7. if(p != NULL){
  8. //存入栈中
  9. stack.push(p);
  10. //遍历左子树
  11. p = p->lchild;
  12. }
  13. else{
  14. //退栈,访问根节点
  15. p = stack.top();
  16. printf("%c ",p->data);
  17. stack.pop();
  18. //访问右子树
  19. p = p->rchild;
  20. }
  21. }//while
  22. }
【后序遍历】

【思路】:T是要遍历树的根指针,后序遍历要求在遍历完左右子树后,再访问根。需要判断根结点的左右子树是否均遍历过。

[cpp] view plaincopy

  1. //后序遍历(非递归)
  2. typedef struct BiTNodePost{
  3. BiTree biTree;
  4. char tag;
  5. }BiTNodePost,*BiTreePost;
  6. void PostOrder2(BiTree T){
  7. stack<BiTreePost> stack;
  8. //p是遍历指针
  9. BiTree p = T;
  10. BiTreePost BT;
  11. //栈不空或者p不空时循环
  12. while(p != NULL || !stack.empty()){
  13. //遍历左子树
  14. while(p != NULL){
  15. BT = (BiTreePost)malloc(sizeof(BiTNodePost));
  16. BT->biTree = p;
  17. //访问过左子树
  18. BT->tag = ‘L‘;
  19. stack.push(BT);
  20. p = p->lchild;
  21. }
  22. //左右子树访问完毕访问根节点
  23. while(!stack.empty() && (stack.top())->tag == ‘R‘){
  24. BT = stack.top();
  25. //退栈
  26. stack.pop();
  27. printf("%c ",BT->biTree->data);
  28. }
  29. //遍历右子树
  30. if(!stack.empty()){
  31. BT = stack.top();
  32. //访问过右子树
  33. BT->tag = ‘R‘;
  34. p = BT->biTree;
  35. p = p->rchild;
  36. }
  37. }//while
  38. }

或者

[cpp] view plaincopy

  1. vector<int> postorderTraversal(TreeNode *root) {
  2. vector<int> result;
  3. if(root == nullptr){
  4. return result;
  5. }//if
  6. stack<TreeNode*> s;
  7. s.push(root);
  8. TreeNode *node;
  9. while(!s.empty()){
  10. node = s.top();
  11. s.pop();
  12. result.insert(result.begin(),node->val);
  13. // 左子树
  14. if(node->left){
  15. s.push(node->left);
  16. }//if
  17. // 右子树
  18. if(node->right){
  19. s.push(node->right);
  20. }//if
  21. }//while
  22. return result;
  23. }
【层次遍历】

【思路】:按从顶向下,从左至右的顺序来逐层访问每个节点,层次遍历的过程中需要用队列。

[cpp] view plaincopy

  1. //层次遍历
  2. void LevelOrder(BiTree T){
  3. BiTree p = T;
  4. //队列
  5. queue<BiTree> queue;
  6. //根节点入队
  7. queue.push(p);
  8. //队列不空循环
  9. while(!queue.empty()){
  10. //对头元素出队
  11. p = queue.front();
  12. //访问p指向的结点
  13. printf("%c ",p->data);
  14. //退出队列
  15. queue.pop();
  16. //左子树不空,将左子树入队
  17. if(p->lchild != NULL){
  18. queue.push(p->lchild);
  19. }
  20. //右子树不空,将右子树入队
  21. if(p->rchild != NULL){
  22. queue.push(p->rchild);
  23. }
  24. }
  25. }

【测试】

输入:(先序)

15 11 8 -1 -1 14 13 -1 -1 -1 20 -1 -1

输出:

代码一:

[cpp] view plaincopy

  1. /*-------------------------------------
  2. *   日期:2015-03-25
  3. *   作者:SJF0115
  4. *   题目: 二叉树各种遍历
  5. *   来源:
  6. *   博客:
  7. ------------------------------------*/
  8. #include <iostream>
  9. #include <vector>
  10. #include <stack>
  11. #include <queue>
  12. using namespace std;
  13. // 二叉树节点结构
  14. struct TreeNode{
  15. int val;
  16. TreeNode *left;
  17. TreeNode *right;
  18. TreeNode(int x):val(x),left(nullptr),right(nullptr){}
  19. };
  20. // 1.创建二叉树
  21. void CreateTree(TreeNode* &root){
  22. int val;
  23. //按先序次序输入二叉树中结点的值,‘-1’表示空树
  24. cin>>val;
  25. // 空节点
  26. if(val == -1){
  27. root = nullptr;
  28. return;
  29. }//if
  30. root = new TreeNode(val);
  31. //构造左子树
  32. CreateTree(root->left);
  33. //构造右子树
  34. CreateTree(root->right);
  35. }
  36. // 2.1 递归先序遍历
  37. void PreOrder(TreeNode* root,vector<int> &result){
  38. if(root == nullptr){
  39. return;
  40. }//if
  41. result.push_back(root->val);
  42. // 左子树
  43. PreOrder(root->left,result);
  44. // 右子树
  45. PreOrder(root->right,result);
  46. }
  47. // 2.2 非递归先序遍历
  48. void PreOrder2(TreeNode* root,vector<int> &result){
  49. if(root == nullptr){
  50. return;
  51. }//if
  52. stack<TreeNode*> s;
  53. s.push(root);
  54. TreeNode *node;
  55. while(!s.empty()){
  56. node = s.top();
  57. s.pop();
  58. result.push_back(node->val);
  59. // 右子树
  60. if(node->right){
  61. s.push(node->right);
  62. }//if
  63. // 左子树
  64. if(node->left){
  65. s.push(node->left);
  66. }//if
  67. }//while
  68. }
  69. // 3.1 递归中序遍历
  70. void InOrder(TreeNode* root,vector<int> &result){
  71. if(root == nullptr){
  72. return;
  73. }//if
  74. // 左子树
  75. InOrder(root->left,result);
  76. result.push_back(root->val);
  77. // 右子树
  78. InOrder(root->right,result);
  79. }
  80. // 3.2 非递归中序遍历
  81. void InOrder2(TreeNode* root,vector<int> &result){
  82. if(root == nullptr){
  83. return;
  84. }//if
  85. stack<TreeNode*> s;
  86. TreeNode *node = root;
  87. while(node != nullptr || !s.empty()){
  88. // 左子树
  89. if(node != nullptr){
  90. s.push(node);
  91. node = node->left;
  92. }//if
  93. // 右子树
  94. else{
  95. node = s.top();
  96. s.pop();
  97. result.push_back(node->val);
  98. node = node->right;
  99. }
  100. }//while
  101. }
  102. // 4.1 递归后序遍历
  103. void PostOrder(TreeNode* root,vector<int> &result){
  104. if(root == nullptr){
  105. return;
  106. }//if
  107. // 左子树
  108. PostOrder(root->left,result);
  109. // 右子树
  110. PostOrder(root->right,result);
  111. result.push_back(root->val);
  112. }
  113. // 4.2 非递归后序遍历
  114. void PostOrder2(TreeNode *root,vector<int> &result) {
  115. if(root == nullptr){
  116. return;
  117. }//if
  118. stack<TreeNode*> s;
  119. s.push(root);
  120. TreeNode *node;
  121. while(!s.empty()){
  122. node = s.top();
  123. s.pop();
  124. result.insert(result.begin(),node->val);
  125. // 左子树
  126. if(node->left){
  127. s.push(node->left);
  128. }//if
  129. // 右子树
  130. if(node->right){
  131. s.push(node->right);
  132. }//if
  133. }//while
  134. }
  135. // 5 层次遍历
  136. void LevelOrder(TreeNode* root,vector<int> &result){
  137. if(root == nullptr){
  138. return;
  139. }//if
  140. queue<TreeNode*> queue;
  141. queue.push(root);
  142. TreeNode *node;
  143. while(!queue.empty()){
  144. node = queue.front();
  145. queue.pop();
  146. result.push_back(node->val);
  147. // 左子树
  148. if(node->left){
  149. queue.push(node->left);
  150. }//if
  151. // 右子树
  152. if(node->right){
  153. queue.push(node->right);
  154. }//if
  155. }//while
  156. }
  157. // 输出结果
  158. void Print(vector<int> result){
  159. int size = result.size();
  160. for(int i = 0;i < size;++i){
  161. cout<<result[i]<<" ";
  162. }//for
  163. cout<<endl;
  164. }
  165. int main(){
  166. freopen("C:\\Users\\Administrator\\Desktop\\c++.txt", "r", stdin);
  167. TreeNode* root = nullptr;
  168. vector<int> result;
  169. // 创建二叉树
  170. cout<<"1. 创建二叉树"<<endl;
  171. CreateTree(root);
  172. cout<<"-----------------------------"<<endl;
  173. cout<<"2.1 递归先序遍历"<<endl;
  174. PreOrder(root,result);
  175. Print(result);
  176. result.clear();
  177. cout<<"-----------------------------"<<endl;
  178. cout<<"2.2 非递归先序遍历"<<endl;
  179. PreOrder2(root,result);
  180. Print(result);
  181. result.clear();
  182. cout<<"-----------------------------"<<endl;
  183. cout<<"3.1 递归中序遍历"<<endl;
  184. InOrder(root,result);
  185. Print(result);
  186. result.clear();
  187. cout<<"-----------------------------"<<endl;
  188. cout<<"3.2 非递归中序遍历"<<endl;
  189. InOrder2(root,result);
  190. Print(result);
  191. result.clear();
  192. cout<<"-----------------------------"<<endl;
  193. cout<<"4.1 递归后序遍历"<<endl;
  194. PostOrder(root,result);
  195. Print(result);
  196. result.clear();
  197. cout<<"-----------------------------"<<endl;
  198. cout<<"4.2 非递归后序遍历"<<endl;
  199. PostOrder2(root,result);
  200. Print(result);
  201. result.clear();
  202. cout<<"-----------------------------"<<endl;
  203. cout<<"5 层次遍历"<<endl;
  204. LevelOrder(root,result);
  205. Print(result);
  206. result.clear();
  207. cout<<"-----------------------------"<<endl;
  208. return 0;
  209. }

测试用例:

输入:

ABC##DE#G##F###

输出:

代码二:

[cpp] view plaincopy

  1. #include<iostream>
  2. #include<stack>
  3. #include<queue>
  4. using namespace std;
  5. //二叉树结点
  6. typedef struct BiTNode{
  7. //数据
  8. char data;
  9. //左右孩子指针
  10. struct BiTNode *lchild,*rchild;
  11. }BiTNode,*BiTree;
  12. //按先序序列创建二叉树
  13. int CreateBiTree(BiTree &T){
  14. char data;
  15. //按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树
  16. scanf("%c",&data);
  17. if(data == ‘#‘){
  18. T = NULL;
  19. }
  20. else{
  21. T = (BiTree)malloc(sizeof(BiTNode));
  22. //生成根结点
  23. T->data = data;
  24. //构造左子树
  25. CreateBiTree(T->lchild);
  26. //构造右子树
  27. CreateBiTree(T->rchild);
  28. }
  29. return 0;
  30. }
  31. //输出
  32. void Visit(BiTree T){
  33. if(T->data != ‘#‘){
  34. printf("%c ",T->data);
  35. }
  36. }
  37. //先序遍历
  38. void PreOrder(BiTree T){
  39. if(T != NULL){
  40. //访问根节点
  41. Visit(T);
  42. //访问左子结点
  43. PreOrder(T->lchild);
  44. //访问右子结点
  45. PreOrder(T->rchild);
  46. }
  47. }
  48. //中序遍历
  49. void InOrder(BiTree T){
  50. if(T != NULL){
  51. //访问左子结点
  52. InOrder(T->lchild);
  53. //访问根节点
  54. Visit(T);
  55. //访问右子结点
  56. InOrder(T->rchild);
  57. }
  58. }
  59. //后序遍历
  60. void PostOrder(BiTree T){
  61. if(T != NULL){
  62. //访问左子结点
  63. PostOrder(T->lchild);
  64. //访问右子结点
  65. PostOrder(T->rchild);
  66. //访问根节点
  67. Visit(T);
  68. }
  69. }
  70. /* 先序遍历(非递归)
  71. 思路:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
  72. */
  73. void PreOrder2(BiTree T){
  74. stack<BiTree> stack;
  75. //p是遍历指针
  76. BiTree p = T;
  77. //栈不空或者p不空时循环
  78. while(p || !stack.empty()){
  79. if(p != NULL){
  80. //存入栈中
  81. stack.push(p);
  82. //访问根节点
  83. printf("%c ",p->data);
  84. //遍历左子树
  85. p = p->lchild;
  86. }
  87. else{
  88. //退栈
  89. p = stack.top();
  90. stack.pop();
  91. //访问右子树
  92. p = p->rchild;
  93. }
  94. }//while
  95. }
  96. /* 中序遍历(非递归)
  97. 思路:T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
  98. 先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。
  99. */
  100. void InOrder2(BiTree T){
  101. stack<BiTree> stack;
  102. //p是遍历指针
  103. BiTree p = T;
  104. //栈不空或者p不空时循环
  105. while(p || !stack.empty()){
  106. if(p != NULL){
  107. //存入栈中
  108. stack.push(p);
  109. //遍历左子树
  110. p = p->lchild;
  111. }
  112. else{
  113. //退栈,访问根节点
  114. p = stack.top();
  115. printf("%c ",p->data);
  116. stack.pop();
  117. //访问右子树
  118. p = p->rchild;
  119. }
  120. }//while
  121. }
  122. //后序遍历(非递归)
  123. typedef struct BiTNodePost{
  124. BiTree biTree;
  125. char tag;
  126. }BiTNodePost,*BiTreePost;
  127. void PostOrder2(BiTree T){
  128. stack<BiTreePost> stack;
  129. //p是遍历指针
  130. BiTree p = T;
  131. BiTreePost BT;
  132. //栈不空或者p不空时循环
  133. while(p != NULL || !stack.empty()){
  134. //遍历左子树
  135. while(p != NULL){
  136. BT = (BiTreePost)malloc(sizeof(BiTNodePost));
  137. BT->biTree = p;
  138. //访问过左子树
  139. BT->tag = ‘L‘;
  140. stack.push(BT);
  141. p = p->lchild;
  142. }
  143. //左右子树访问完毕访问根节点
  144. while(!stack.empty() && (stack.top())->tag == ‘R‘){
  145. BT = stack.top();
  146. //退栈
  147. stack.pop();
  148. BT->biTree;
  149. printf("%c ",BT->biTree->data);
  150. }
  151. //遍历右子树
  152. if(!stack.empty()){
  153. BT = stack.top();
  154. //访问过右子树
  155. BT->tag = ‘R‘;
  156. p = BT->biTree;
  157. p = p->rchild;
  158. }
  159. }//while
  160. }
  161. //层次遍历
  162. void LevelOrder(BiTree T){
  163. BiTree p = T;
  164. //队列
  165. queue<BiTree> queue;
  166. //根节点入队
  167. queue.push(p);
  168. //队列不空循环
  169. while(!queue.empty()){
  170. //对头元素出队
  171. p = queue.front();
  172. //访问p指向的结点
  173. printf("%c ",p->data);
  174. //退出队列
  175. queue.pop();
  176. //左子树不空,将左子树入队
  177. if(p->lchild != NULL){
  178. queue.push(p->lchild);
  179. }
  180. //右子树不空,将右子树入队
  181. if(p->rchild != NULL){
  182. queue.push(p->rchild);
  183. }
  184. }
  185. }
  186. int main()
  187. {
  188. BiTree T;
  189. CreateBiTree(T);
  190. printf("先序遍历:\n");
  191. PreOrder(T);
  192. printf("\n");
  193. printf("先序遍历(非递归):\n");
  194. PreOrder2(T);
  195. printf("\n");
  196. printf("中序遍历:\n");
  197. InOrder(T);
  198. printf("\n");
  199. printf("中序遍历(非递归):\n");
  200. InOrder2(T);
  201. printf("\n");
  202. printf("后序遍历:\n");
  203. PostOrder(T);
  204. printf("\n");
  205. printf("后序遍历(非递归):\n");
  206. PostOrder2(T);
  207. printf("\n");
  208. printf("层次遍历:\n");
  209. LevelOrder(T);
  210. printf("\n");
  211. return 0;
  212. }

出处:http://blog.csdn.NET/sjf0115/article/details/8645991

时间: 2024-10-07 19:32:30

二叉树的先序/中序/后序/层次遍历的相关文章

数据结构:二叉树(前,中,后,层次)非递归遍历。

#include <iostream> #include <stack> #include <map> #include <queue> #include <string.h> using namespace std; struct Node { char data; Node *left; Node *right; Node(char d = char()):data(d),left(NULL),right(NULL){} }; class T

leetcode(144,94,145,102)中迭代版的二叉树的前、中、后、层级遍历

//前序遍历class Solution{ public: vector<int> preorderTraversal(TreeNode *root){ vector<int> res; stack<TreeNode*> s; TreeNode* p = root; if(!p) return res; s.push(p); while(!s.empty()){ p = s.top(); s.pop(); res.push_back(p->val); if(p-&

Java数据结构四之——二叉树的前、中、后序遍历

程序来自Program Creek 前 Preorder binary tree traversal is a classic interview problem about trees. The key to solve this problem is to understand the following: What is preorder? (parent node is processed before its children) Use Stack from Java Core lib

算法进化历程之“根据二叉树的先序和中序序列输出后序序列”

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 前不久在看到一个作业"根据二叉树的先序和中序序列输出后序序列",当时我参考<数据结构与算法(C语言)习题集>上的做法,先根据先中序序列确定一颗二叉树,然后后序遍历二叉树输出后序序列. 函数采用了递归算法,利用函数传入的先序和中序序列的左右边界,确定要处理的序列段,生成相应的二叉树. 基本思路是,把该段先序序列的第一个元素作为当前二叉树的根结点,然后在中序序列找到根结点.根结点

通过二叉树的中序序列和后序序列获取前序序列

二叉树的遍历方式常见的三种是:先序遍历(ABC).中序遍历(BAC).后序遍历(BCA) 先序遍历: 若二叉树为空,则空操作:否则: 访问根结点; 先序遍历左子树: 先序遍历右子树. 中序遍历: 若二叉树为空,则空操作:否则: 中序遍历左子树: 访问根结点: 中序遍历右子树. 后序遍历: 若二叉树为空,则空操作:否则: 后序遍历左子树: 后序遍历右子树: 访问根结点. 在学习到 根据遍历序列确定二叉树 时,知道了:可以通过二叉树的先中或者中后遍历序列唯一确定一棵二叉树. 根据算法描述 使用jav

先序序列和后序序列并不能唯一确定二叉树

数据结构的基础知识中重要的一点就是能否根据两种不同遍历序列的组合(有三种:先序+中序,先序+后序,中序+后序),唯一的确定一棵二叉树.然后就是根据二叉树的不同遍历序列(先序.中序.后序),重构二叉树.显然,这三种组合并不是都能唯一确定二叉树的,其中先序+后序就不能唯一确定一棵二叉树,其他两种组合可以唯一的确定一颗二叉树. 由先序序列和后序序列不能唯一确定一棵二叉树,因无法确定左右子树两部分. 反例:任何结点只有左子树的二叉树和任何结点只有右子树的二叉树,其前序序列相同,后序序列相同,但却是两棵不

中序表达式转后序表式式

中序表达式转后序表式式: 将中序表达式所有括号补全,然后将所有运算符向右移出无匹配的第一个右括号,去掉括号即为后序表式式 举例: 原式:a+b*(c+d/e) 补全括号:(a+(b*(c+(d/e)))) 操作符右移:(a(b(c(de)/)+)*)+ 去掉括号:abcde/+*+ 中序表达式转前序表式式: 将中序表达式所有括号补全,然后将所有运算符向左移出无匹配的第一个左括号,去掉括号即为前序表式式 举例: 原式:a+b*(c+d/e) 补全括号:(a+(b*(c+(d/e)))) 操作符右移

二叉树的前中后以及层次遍历

#include "stdio.h" #include "malloc.h" #define datatype char  typedef struct bT { datatypedata; struct bT *lt,*rt; }* bitree,BiNode; void preExCreate(bitree bt); /*递归实现*/ void FprePost(bitree bt) { if(bt) { printf("%c",bt->

递归非递归的二叉树遍历(递归前中后,非递归前中后,层次遍历,凹入打印法等)

由于所有的递归算法都可以借助于堆栈转换成循环结构的非递归算法.方法一:形式化模拟转换.方法二:根据要求解问题的特点设计借助于堆栈的循环结构算法.而此次正好是利用第二种按方法求解. 1.1非递归前序遍历: 首先利用下图来设计非递归前序遍历算法思想: 堆栈结构体如下: #define size 100 typedef struct { DataType data[size]; int tag[100]; //这个是在非递归后序中用到 int top : }SeqStack : (1)初始化设置一个堆

hdu1710-Binary Tree Traversals (由二叉树的先序序列和中序序列求后序序列)

http://acm.hdu.edu.cn/showproblem.php?pid=1710 Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4210    Accepted Submission(s): 1908 Problem Description A binary tree is a