leecode 解题总结:94. Binary Tree Inorder Traversal

来源:互联网 发布:淘宝上九块九包邮 编辑:程序博客网 时间:2024/06/03 16:10
#include <iostream>#include <stdio.h>#include <vector>#include <stack>#include <unordered_map>using namespace std;/*问题:Given a binary tree, return the inorder traversal of its nodes' values.For example:Given binary tree [1,null,2,3],   1    \     2    /   3return [1,3,2].Note: Recursive solution is trivial, could you do it iteratively?分析:对二叉树终须遍历,输出遍历后结果。中序遍历实际上就是左根右。举例:       106      14  2   8   12  16   3 7 9如果当前节点有左孩子,就继续遍历左孩子节点;直到当前节诶点没有左孩子,说明此时当前节点是子树的根节点,然后把当前节点保存在结果集,如果当前节点还有右孩子;把右孩子存入结果集,并回退到当前节点的父节点,其父节点发现左孩子已经访问过,则把自身压入结果集,如果该父节点存在右孩子,把右孩子压入结果集。大致的过程是:设当前1】存储根节点到栈中。2】获取栈顶节点,根据该节点,找到最左边节点,期间通过一个栈存放沿途访问到的节点【该最左边节点也压入到栈中】   找到最左边节点后。3】存储该节点值到结果集,弹出该节点,并保存该节点的右孩子到栈中。转步骤2】栈空,算法结束输入:10(节点个数)10 6 14 2 8 12 16 3 7 9(所有结点的值)d 2 3(当前行为第i行,初始为1,表示第i个节点有d:两个,l:一个左孩子,r:一个右孩子,后面跟孩子节点编号,z无孩子结点)d 4 5d 6 7r 8d 9 10zzzzz输出:2 3 6 7 8 9 10 12 14 16(中序遍历结果)关键:1 1】存储根节点到栈中。2】获取栈顶节点,根据该节点,找到【易错,未访问过的】最左边节点,期间通过一个栈存放沿途访问到的节点【该最左边节点也压入到栈中】   找到最左边节点后。3】存储该节点值到结果集,弹出该节点,并保存该节点的右孩子到栈中。转步骤2】栈空,算法结束2 访问标记可以用哈希map来做。也可以获取到最左边结点后,设置最左边结点为空,那么如果回到父节点,再次尝试访问左结点的时候,就不会继续向下遍历了*/struct TreeNode {    int val;    TreeNode *left;     TreeNode *right;    TreeNode(int x) : val(x), left(NULL), right(NULL) {}TreeNode():left(NULL), right(NULL){}};class Solution {public:TreeNode* findLeftestNode(TreeNode* node ,stack<TreeNode*>& nodes , unordered_map<TreeNode* , int>& visited ){if(NULL == node){return NULL;}TreeNode* tempNode = node;//寻找一个节点最左边的节点://如果当前节点有左孩子就继续沿着左孩子寻找;如果当前节点没有左孩子,就返回该节点本身while(node){//这里如果子节点已经遍历过滤,需要pass,如何判定子节点是否已经访问过,用哈希mapif(node->left){//如果孩子节点已经访问过,直接返回当前节点if(visited.count(node->left)){return node;}node = node->left;//存储沿途的节点,用于后续向上回退时能够找到父节点nodes.push(node);}//无左孩子,直接返回当前节点else{return node;}}return node;}    vector<int> inorderTraversal(TreeNode* root) {vector<int> result;        if(NULL == root){return result;}stack<TreeNode*> nodes;nodes.push(root);TreeNode* node;TreeNode* leftestNode;unordered_map<TreeNode* , int> visited;while(!nodes.empty()){//找到栈顶节点,并寻找最左边节点node = nodes.top();leftestNode = findLeftestNode(node , nodes , visited);//找到最左边节点,将节点的值存储到结果集,如果其存在右孩子,将其右孩子节点存储到栈中if(leftestNode){result.push_back(leftestNode->val);}nodes.pop();visited[leftestNode] = 1;//设置访问标记,当前弹出的节点是最左边节点//右孩子不空,才压入if(leftestNode->right){nodes.push(leftestNode->right);}}return result;    }};const int MAXSIZE = 10000;TreeNode gNodeArr[MAXSIZE];int gIndex;TreeNode* createNode(int value){++gIndex;gNodeArr[gIndex].left = gNodeArr[gIndex].right = NULL;gNodeArr[gIndex].val = value;return &gNodeArr[gIndex];}void print(vector<int>& result){if(result.empty()){cout << "no result" << endl;return;}int size = result.size();for(int i = 0 ; i < size ; i++){cout << result.at(i) << ", " ;}cout << endl;}void process(){ int value; int num; Solution solution; vector<int> result; char ch; int leftIndex; int rightIndex; while(cin >> num ) { gIndex = 0; for(int i = 0 ; i < num ; i++) { cin >> value; createNode(value); } for(int i = 1 ; i <= num ; i++) { cin >> ch; if('d' == ch) { cin >> leftIndex >> rightIndex; gNodeArr[i].left = &gNodeArr[leftIndex]; gNodeArr[i].right = &gNodeArr[rightIndex]; } else if('l' == ch) { cin >> leftIndex; gNodeArr[i].left = &gNodeArr[leftIndex]; } else if('r' == ch) { cin >> rightIndex; gNodeArr[i].right = &gNodeArr[rightIndex]; } } //下面开始中序遍历 result = solution.inorderTraversal(&gNodeArr[1]); print(result); }}int main(int argc , char* argv[]){process();getchar();return 0;}

0 0
原创粉丝点击