Problem:
  实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式

Solution:
  切记递归规则:
  先遍历根节点,然后是左孩子,右孩子,
  根据不同的打印位置来确定中序、前序、后续遍历。

Code:

  

 #pragma once
 #include <iostream>
 #include <vector>
 #include <queue>
 #include <stack>
 #include <string>
 #include <sstream>

 using namespace std;

 struct Node
 {
     int val;
     Node* lchild;
     Node* rchild;
     Node() :val(a), lchild(NULL), rchild(NULL) {}
 };

 void Create1(Node*& root, vector<int>num, int i)//前序构造树
 {
     )
         root = NULL;
     else if (i < num.size())
     {
         root = new Node(num[i]);
         Create1(root->lchild, num, i + );
         Create1(root->rchild, num, i + );
     }
 }

 void Create2(Node*& root, vector<int>num)//层序构造树
 {
     queue<Node*>q;
     root = ]);
     q.push(root);
     ;
     while (i < num.size() && !q.empty())
     {
         Node* p = q.front();
         q.pop();
         if (!p)//空节点p
             break;
         )
             p->lchild = new Node (num[i++]);
         )
             p->rchild = new Node (num[i++]);
         q.push(p->lchild);
         q.push(p->rchild);
     }
 }

 void PreTravel(Node* root)//前序遍历
 {
     if (!root)
         return;
     cout << root->val << "  ";
     PreTravel(root->lchild);
     PreTravel(root->rchild);
 }

 void NotPreTravel(Node* root)//非递归前序遍历
 {
     stack<Node*>s;
     if (root)
     {
         s.push(root);
         while (!s.empty())
         {
             root = s.top();
             cout << root->val << "  ";
             s.pop();
             if (root->rchild)
                 s.push(root->rchild);
             if (root->lchild)
                 s.push(root->lchild);
         }
     }
 }

 void MidTravel(Node* root)//中序遍历
 {
     if (!root)
         return;

     MidTravel(root->lchild);
     cout << root->val << "  ";
     MidTravel(root->rchild);
 }

 void NotMidTravel(Node* root)//非递归中序遍历
 {
     stack<Node*>s;
     if (root)
     {
         while (!s.empty() || root)
         {
             if (root)
             {
                 s.push(root);
                 root = root->lchild;
             }
             else
             {
                 root = s.top();
                 s.pop();
                 cout << root->val << "  ";
                 root = root->rchild;
             }
         }
     }
 }

 void LastTravel(Node* root)//后序遍历
 {
     if (!root)
         return;
     LastTravel(root->lchild);
     LastTravel(root->rchild);
     cout << root->val << "  ";
 }

 void NotLastTravel(Node* root)//非递归后序遍历
 {
     stack<Node*>s1;
     stack<Node*>s2;
     if (root)
     {
         s1.push(root);
         while (!s1.empty())
         {
             root = s1.top();
             s1.pop();
             s2.push(root);
             if (root->lchild)
                 s1.push(root->lchild);
             if(root->rchild)
                 s1.push(root->rchild);
         }
         while (!s2.empty())
         {
             root = s2.top();
             s2.pop();
             cout << root->val << "  ";
         }
     }
 }

 void NotLastTravel2(Node* root)//非递归后序遍历,使用一个栈
 {
     stack<Node*>s;
     if (root)
     {
         s.push(root);
         Node* p;
         while (!s.empty())
         {
             p = s.top();
             if (p->lchild && root != p->lchild && root != p->rchild)
                 s.push(p->lchild);
             else if (p->rchild && root != p->rchild )
                 s.push(p->rchild);
             else
             {
                 cout << p->val << "  ";
                 s.pop();
                 root = p;
             }
         }

     }
 }

 string getSpace(int num)
 {
     string space = " ";
     ; i < num; ++i)
         space.append(" ");
     return space;
 }

 void PrintShape(Node* root, int h, string c, int len)
 {
     if (root)
     {
         PrintShape(root->rchild, h + , "v", len);
         string val;
         stringstream ss;
         ss << root->val;
         ss >> val;
         val = c + val + c;
         int lenM = val.length();
         ;
         int lenR = len - lenM - lenL;
         val = getSpace(lenL) + val + getSpace(lenR);
         cout << getSpace(h*len) + val << endl;
         PrintShape(root->lchild, h + , "^", len);
     }

 }

 //直观地打印一颗树,即打印一横向的树,每个节点的左上角节点为其父节点
 void PrintTree(Node* root)
 {
     cout << "The shape of tree is: " << endl;
     cout << "===============================================" << endl;
     PrintShape(root, , );
     cout << "===============================================" << endl;
 }

 void Test()
 {
     //我们使用多种方法来构造一颗树:
     //                 1
     //            2            3
     //         4     5     6     7
     //        8 9  10 11 12 N  N  NULL
     //  使用层序遍历来打印树

     Node* root1 = NULL;
     vector<,,,,,,,,,,,-,,-,- };
     Create1(root1, num1, );//前序构造树

     Node* root2 = NULL;
     vector<,,,,,,,,,,,,-,-,-};
     Create2(root2, num2);//层序构造树

     cout << endl << "==============前序遍历============" << endl;
     PreTravel(root2);//前序遍历

     cout << endl << "===============中序遍历=============" << endl;
     MidTravel(root2);//中序遍历

     cout << endl << "===============后序遍历============" << endl;
     LastTravel(root2);//后序遍历

     cout << endl << "===============非递归前序遍历============" << endl;
     NotPreTravel(root2);//非递归前序遍历

     cout << endl << "===============非递归中序遍历============" << endl;
     NotMidTravel(root2);//非递归中序遍历

     cout << endl << "===============非递归后序遍历============" << endl;
     NotLastTravel2(root2);//非递归后序遍历

     cout << endl << "===============打印树============" << endl;
     PrintTree(root2);

     ;

 }

左神算法基础班4_1&2实现二叉树的先序、中序、后序遍历,包括递归方式和非递归的更多相关文章

  1. 左神算法基础班5_1设计RandomPool结构

    Problem: 设计RandomPool结构 [题目] 设计一种结构,在该结构中有如下三个功能: insert(key):将某个key加入到该结构,做到不重复加入. delete(key):将原本在 ...

  2. 左神算法进阶班1_5BFPRT算法

    在无序数组中找到第k大的数1)分组,每N个数一组,(一般5个一组)2)每组分别进行排序,组间不排序3)将每个组的中位数拿出来,若偶数,则拿上 / 下中位数, 成立一个一个新数组.4)新数组递归调用BF ...

  3. 左神算法进阶班3_1构造数组的MaxTree

    题目 一个数组的MaxTree定义: 数组必须没有重复元素 MaxTree是一棵二叉树,数组的每一个值对应一个二叉树节点 包括MaxTree树在内且在其中的每一棵子树上,值最大的节点都是树的头 给定一 ...

  4. 左神算法进阶班1_4Manacher算法

    #include <iostream> #include <string> using namespace std; //使用manacher算法寻找字符中最长的回文子串 in ...

  5. 左神算法进阶班1_1添加最少字符得到原字符N次

    Problem: 给定一个字符串str1,只能往str1的后面添加字符变成str2. 要求1:str2必须包含两个str1,两个str1可以有重合,但是不能以同一个位置开头. 要求2:str2尽量短最 ...

  6. 左神算法进阶班5_4设计可以变更的缓存结构(LRU)

    [题目] 设计一种缓存结构,该结构在构造时确定大小,假设大小为K,并有两个功能: set(key, value):将记录(key, value)插入该结构. get(key):返回key对应的valu ...

  7. 左神算法进阶班4_2累加和为aim的最长子数组

    [题目] 给定一个数组arr,和一个整数aim,求在arr中,累加和等于num的最长子数组的长度 例子: arr = { 7,3,2,1,1,7,7,7 } aim = 7 其中有很多的子数组累加和等 ...

  8. 左神算法进阶班8_1数组中累加和小于等于aim的最长子数组

    [题目] 给定一个数组arr,全是正数:一个整数aim,求累加和小于等于aim的,最长子数组,要求额外空间复杂度O(1),时间复杂度O(N) [题解] 使用窗口: 双指针,当sum <= aim ...

  9. 左神算法进阶班6_1LFU缓存实现

    [题目] LFU也是一个著名的缓存算法,自行了解之后实现LFU中的set 和 get 要求:两个方法的时间复杂度都为O(1) [题解] LFU算法与LRU算法很像 但LRU是最新使用的排在使用频率最前 ...

随机推荐

  1. 使用Git 上传文件到云端(版本库)

    第一步:本地初始化Git版本库 git init 第二步:链接码云(云端) git remote add orgin "你的远程仓库地址"(复制链接后结尾是.git,如果没有记得加 ...

  2. 廖雪峰Java13网络编程-1Socket编程-2TCP编程

    1. Socket 在开发网络应用程序的时候,会遇到Socket这个概念. Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据 ...

  3. JAVA javac

    { 用法: javac <options> <source files>其中, 可能的选项包括:  -g                         生成所有调试信息  - ...

  4. DataWorks2.0的“业务流程”与1.0的“工作流”的对比

    DatwWorks终于升级2.0了,心情万分激动之余,又有一丝担忧.因为,没法再创建新的旧版工作流了...新版抛弃了“工作流”这个概念,引入了“业务流程”和“解决方案”两个新的概念.于是,作为团队Le ...

  5. PHP FTP 常量

    常量 描述 PHP FTP_ASCII   3 FTP_TEXT   3 FTP_BINARY   3 FTP_IMAGE   3 FTP_TIMEOUT_SEC   3 FTP_AUTOSEEK   ...

  6. Java中获取前一天和后一天时间

    今天在开发项目的时候遇到一个问题就是怎么获取当前时间的前一天和后一天,这个实现的逻辑并不复杂,自己要写的话的也不是难事,但是貌似感觉没必要自己写这样的方法,想想Java中的Calendar类应该有这样 ...

  7. DELPHI中如何闪烁应用程序窗口或任务栏按钮

    使用FlashWindowEx函数: 一.设置FlashWInfoDelphi中TFlashWInfo申明如下:TypeTFlashWInfo = record cbSize : LongInt; h ...

  8. NX二次开发-UFUN移动工程图视图UF_DRAW_move_view

    #include <uf.h> #include <uf_draw.h> #include <uf_drf.h> #include <uf_obj.h> ...

  9. Java 并发总结(三)

    锁优化及注意事项 有助于提高锁的性能 减小所持有时间:例如不要对方法直接加锁,而是在方法中对具体访问临界资源的代码加锁 减小锁粒度:如ConcurrentHashMap 用读写锁代替独占锁 锁分离:如 ...

  10. 数据结构C++版-线性表

    PS:资料来源慕课网视频. 一.什么是线性表 线性表是n个数据元素的有限序列. 分类: 二.补充知识点 1.栈和队列有出操作.入操作,对应线性表(数组)为插入元素和删除元素,而线性表中要获取指定元素值 ...