二叉树递归与非递归遍历,最近公共父节点算法

#include <iostream>
#include <stack>
using namespace std;

#define MAX 100           //字符串最大长度
typedef struct Node       //二叉树结点
{
    char data;
    Node *lchild,*rchild;
} *Btree;

void createBT(Btree &t);  //先序构造二叉树

void preorder(Btree &t);  //二叉树递归先序遍历
void inorder(Btree &t);   //递归中序遍历
void postorder(Btree &t); //递归后序遍历

void preorderbyStack(Btree &t); //先序非递归遍历
void inorderbyStack(Btree &t);  //中序非递归遍历
void postorderbyStack(Btree &t);//后序非递归遍历

/*****************最近公共父结点算法LCF*******************/
int findNode1(Btree &t,char ch,char p[]); //找出结点1到根的路径
int findNode2(Btree &t,char ch,char q[]); //找出结点2到根的路径

void compare(char *p,char *q);            //比较两条路径,找到第一个公共结点
static int i = 0;
static int j = 0;
/*****************最近公共父结点算法LCF*******************/

void createBT(Btree &t)   //先序创建二叉树 #表示空指针
{
    char ch;
    cin>>ch;
    if(ch == ‘#‘) t = NULL;

    else
    {
        if(!(t = new Node)) exit(1);

        t ->data = ch;    //递归创建二叉树
        createBT(t->lchild);
        createBT(t->rchild);
    }
}

void preorder(Btree &t)
{
    if(t == NULL)
        return ;
    else
    {
        cout<<t->data<<" ";
        preorder(t->lchild);
        preorder(t->rchild);
    }
}

void inorder(Btree &t)
{
    if(!t)
        return;
    else
    {
        inorder(t->lchild);
        cout<<t->data<<" ";
        inorder(t->rchild);
    }
}

void postorder(Btree &t)
{
    if(!t)
        return;
    else
    {
        postorder(t->lchild);
        postorder(t->rchild);
        cout<<t->data<<" ";
    }
}

void preorderbyStack(Btree &t)
{
    stack<Node*>s;
    Node *p = t;
    while (p || !s.empty())
    {
        if(p)
        {
            cout<<p->data<<" ";    //先序遍历二叉树,先访问根节点,再访问左子树
            s.push(p);
            p = p->lchild;
        }
        else
        {
            p = s.top();
            s.pop();
            p = p->rchild;
        }
    }
}

void inorderbyStack(Btree &t)
{
    stack<Node*>s;

    Node *p = t;

    while (p || !s.empty())
    {
        if(p)
        {
            s.push(p);
            p = p->lchild;
        }
        else
        {
            p = s.top();
            cout<<p->data<<" ";   //中序遍历二叉树,先访问左子树
            s.pop();
            p = p->rchild;
        }
    }
}

void postorderbyStack(Btree &t)
{
    stack<Node*> s;

    Node *p = t;
    Node *flag = nullptr;

    while (p || !s.empty())
    {
        if(p)                      //后序遍历先访问左结点,再右结点,最后根结点
        {
            s.push(p);
            p = p->lchild;
        }
        else
        {
            p = s.top();
            if( p->rchild&&p->rchild != flag) //如果右子树不为空且没有被访问过
            {
                p = p->rchild;                //转到右子树
                s.push(p);
                p = p->lchild;
            }
            else                            //如果右子树为空,当前结点为访问结点
            {
                s.pop();
                cout<<p->data<<" ";

                flag = p;                  //把刚刚访问的结点做标记,防止重复访问
                p = nullptr;               //把p置为空指针,如果不置位空。还要压入栈一次,就造成死循环
            }
        }
    }
}

bool isEmpty(Btree &t)
{
    return t == NULL?true:false;
}

int findNode1(Btree &t,char ch,char p[])
{
    if(!t)
        return 0;
    else if(t->data == ch)             //从所给的结点出发,搜索到达根节点的路径,并将路径记录下来
    {
        *(p+i) = t->data;
        ++i;
        return 1;
    }
    else
    {
        if(findNode1(t->lchild, ch, p))
        {
            *(p+i) = t->data;
            ++i;
            return 1;
        }
        else if(findNode1(t->rchild, ch, p))
        {
            *(p+i) = t->data;
            ++i;
            return 1;
        }
        else
            return 0;
    }
}

int findNode2(Btree &t,char ch,char q[])
{
    if(!t)
        return 0;
    else if(t->data == ch)
    {
        *(q+j) = t->data;
        ++j;
        return 1;
    }
    else
    {
        if(findNode2(t->lchild, ch, q))
        {
            *(q+j) = t->data;
            ++j;
            return 1;
        }
        else if(findNode2(t->rchild, ch, q))
        {
            *(q+j) = t->data;
            ++j;
            return 1;
        }
        else
            return 0;
    }
}

void compare(char *p,char *q)   //比较两条路径,第一个不同的路径点的父结点就是其公共父结点
{
    i--;
    j--;
    while(p[i] == q[j])
    {
        i--;
        j--;
    }

    cout<<"LCF is :"<<p[i+1]<<endl;
}

int main()
{
    //测试用例:abc##de#g##f###

    Btree t = new Node;
    createBT(t);
    preorder(t);
    cout<<endl;
    preorderbyStack(t);
    cout<<endl;
    inorder(t);
    cout<<endl;
    inorderbyStack(t);
    cout<<endl;
    postorder(t);
    cout<<endl;
    postorderbyStack(t);
    cout<<endl;

    char a[MAX];
    char b[MAX];

    findNode1(t, ‘c‘,a);
    findNode2(t, ‘e‘,b);

    compare(a, b);
    return 0;
}

前序构造二叉树 字符#表示空。

二叉树的递归遍历与非递归遍历。后者借助栈

最近公共父节点是指对于二叉树中的两个结点 找到最近的公共父节点

二叉树递归与非递归遍历,最近公共父节点算法,布布扣,bubuko.com

时间: 2024-12-31 16:45:33

二叉树递归与非递归遍历,最近公共父节点算法的相关文章

二叉树(12)----查找两个节点最低祖先节点(或最近公共父节点等),递归和非递归

1.二叉树定义: typedef struct BTreeNodeElement_t_ { void *data; } BTreeNodeElement_t; typedef struct BTreeNode_t_ { BTreeNodeElement_t *m_pElemt; struct BTreeNode_t_ *m_pLeft; struct BTreeNode_t_ *m_pRight; } BTreeNode_t; 2.查找二叉树中两个节点的最低祖先节点(或最近公共父节点等) 最低祖

JAVA递归、非递归遍历二叉树(转)

原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { private char date; private BinTree lchild; private BinTree rchild; public BinTree(char c) { date = c; } // 先序遍历递归 public static void preOrder(BinTree t) {

Java数据结构系列之——树(4):二叉树的中序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树的中序遍历:递归与非递归实现 * * @author wl * */ public class BiTreeInOrder { // 中序遍历的递归实现 public static void biTreeInOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreeInOrderByRecursi

二叉树遍历递归与非递归实现

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 二叉树遍历是二叉树中非常基础的部分,也是学习二叉树必须熟练掌握的部分,下面我们先给出二叉树三种遍历方式的定义,并通过举例来说明二叉树遍历的过程. 二叉树的遍历分为:前序遍历(也叫先序遍历).中序遍历.后序遍历.所谓前.中.后都是根据当前子树根结点相对左右孩子的位置而言,也就是说: 前序遍历:根结点在前,即:根 ----->左------->右: 中序遍历:根结点在中间,即:左------>根------>右: 后序遍历:根结点在最

二叉树三种遍历(递归以及非递归实现)

package com.shiyeqiang.tree; import java.util.Stack; public class BiTree { public static void main(String[] args) { // 首先构造叶子节点 BiTree leafA1 = new BiTree(4); BiTree leafA2 = new BiTree(5); BiTree leafB1 = new BiTree(6); BiTree leafB2 = new BiTree(7)

二叉树遍历算法总结(递归与非递归)

一:前言 二叉树的遍历方法分四种:前序,中序,后序以及层次遍历. 其中,前中后遍历方法的实现分递归和非递归,非递归遍历的实现需要借助于栈. 实际上,递归的调用就是一种栈的实现,所以,非递归遍历就需要人工借助栈结构来实现. 而层次遍历需要借助队列. 二:前中后序遍历 递归遍历: 递归遍历的思想和方法很简单,通过调整输出语句来实现前,中,后三种遍历. 代码如下: 1 void show(BiTree T) 2 { 3 if(T) 4 { 5 printf("%c ",T->data)

二叉树的前序、中序、后序遍历(递归、非递归)实现

本文部分来源于CSDN兰亭风雨大牛的原创.链接为http://blog.csdn.net/ns_code/article/details/12977901 二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的.二叉树有前.中.后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的).下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍

二叉树的递归和非递归遍历

// 本次练习的是  二叉树的  递归和非递归  遍历   以及二叉树的  节点数  高度  叶子节点数   和查找功能  //如果要是变量在函数栈回归时不回归原值,则可以用引用// #define _CRT_SECURE_NO_WARNINGS 1#include<iostream>#include<stack>#include<queue>using namespace std; template<class T>struct BinaryTreeNod

Java数据结构系列之——树(5):二叉树的后序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树后序遍历的递归与非递归实现 * * @author wl * */ public class BitreePostOrder { // 后序遍历的递归实现 public static void biTreePostOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreePostOrderByRe