数据结构中二叉树的递归遍历与非递归遍历

来源:互联网 发布:志强软件 编辑:程序博客网 时间:2024/05/16 18:18

二叉树的遍历分为前序遍历、中序遍历和后序遍历三种,其遍历顺序分别为根-左-右,左-根-右和左-右-根。
二叉树的数据结果如下:

struct TreeNode{    TreeNode *left;    TreeNode *right;    int val;};

对于递归遍历,三种遍历顺序有一定的相似性,所以比较简单:

//前序遍历void preorder(TreeNode *root, vector<int> &path){    if(root != NULL)    {        path.push_back(root->val);        preorder(root->left, path);        preorder(root->right, path);    }}//中序遍历void Inorder(TreeNode *root, vector<int> &path){    if(root != NULL)    {               Inorder(root->left, path);        path.push_back(root->val);        Inorder(root->right, path);    }}//后续遍历void postorder(TreeNode *root, vector<int> &path){    if(root != NULL)    {               postorder(root->left, path);                postorder(root->right, path);        path.push_back(root->val);    }}

对于非递归遍历,只能借助栈来完成,就稍微有点复杂了。

//非递归前序遍历void preorderTraversal(TreeNode *root, vector<int> &path){    stack<TreeNode *> s;    TreeNode *p = root;    while(p||!s.empty())    {        while(p)//顺序遍历根节点,直到二叉树左子树为空        {            path.push_back(p->val);            s.push(p);            p=p->left;        }        if(!s.empty())        {            p=s.top();//获得栈顶节点,从而开始遍历右子树            s.pop();            p=p->right;        }    }}
//非递归中序遍历void inorderTraversal(TreeNode *root, vector<int> &path){    stack<TreeNode *> s;    TreeNode *p = root;    while(p||!s.empty())    {           while(p)        {            s.push(p);            p=p->left;        }        if(!s.empty())        {            p=s.top();//获得栈顶结点            path.push_back(p->val);            s.pop();            p=p->right;        }    }}

对于非递归后续遍历,其思路如下:
对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,但是此时不能将其出栈并访问,因此其右孩子还未被访问。所以接下来按照相同的规则对其右子树进行相同的处理,当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。

//非递归后续遍历struct TempNode{    TreeNode *btnode;    bool isFirst;};void postorderTraversal(TreeNode *root, vector<int> &path){    stack<TempNode *> s;    TreeNode *p = root;    TempNode *temp;    while(p != NULL || !s.empty())    {        while(p != NULL) //沿左子树一直往下搜索,直至出现没有左子树的结点        {            TempNode *tempNode = new TempNode;            tempNode->btnode = p;            tempNode->isFirst = true;            s.push(tempNode);            p = p->left;        }        if(!s.empty())        {            temp = s.top();            s.pop();            if(temp->isFirst == true)   //表示是第一次出现在栈顶            {                temp->isFirst = false;                s.push(temp);                p = temp->btnode->right;            }            else  //第二次出现在栈顶            {                path.push_back(temp->btnode->val);                p = NULL;            }        }    }}
0 0
原创粉丝点击