二叉树的遍历及相关题目

二叉树的遍历及相关题目

1.1二叉树遍历的概念

二叉树结构体的定义:

typedef struct node

{

  ElemType data;

  struct node * lchild;

  struct node * rchild;

}

二叉树的遍历是指按照一定的次序访问二叉树中的所有的节点,并且每个节点仅访问一次的过程。

若规定先遍历左子树,后遍历右子树,则对于非空二叉树,可得到如下3种递归的遍历方法:

(1)先序遍历

访问根节点,先序遍历左子树,先序遍历右子树。(根,左,右)

(2)中序遍历

中序遍历左子树,访问根节点,中序遍历右子树。(左,根,右)

(3)后序遍历

后序遍历左子树,后序遍历右子树,访问根节点。(左,右,根)

除此之外也有层次遍历。先访问根节点,在从左到右访问第二层的所有节点,从左到右访问第三层的所有节点......

1.2二叉树遍历递归算法

先序遍历递归算法:

void PreOrder(BTNode * b)

{

  if(n != NULL)

  {

    cout<<b->data;

    PreOrder(b->lchild);

    PreOrder(b->rchild);

  }

}

  

中序遍历递归算法

void InOrder(BTNode * b)

{

  if(n != NULL)

  {

    InOrder(b->lchild);

    cout<<b->data;

    InOrder(b->rchild);

  }

}

 

后序遍历递归算法:

void PostOrder(BTNode * b)

{

  if(b != NULL)

  {

    PostOrder(b->lchild);

    PostOrder(b->rchild);

    cout<<b->data;

  }

}

 

题目1:输出一个给定二叉树的所有的叶子节点:

void DispLeaf(BTNode * b)

{

  if(b != NULL)

 

  {

 

    if(b->lchild == NULL && b->rchild == NULL)

      cout<<b->data;

    DispLeaf(b->lchild);

    DispLeaf(b->rchild);

  }

}

以上算法采用先序遍历输出了所有的叶子节点,所以叶子节点是从左到右输出的。从右到左输出所有的叶子节点就需要才用后序遍历的思想。

void DispLeaf1(BTNode * b)

{

  if(b != NULL)

  {

    if(b->lchild == NULL && b->rchild == NULL)

      cout<<b->data;

    DispLeaf1(b->rchild);

    DispLeaf1(b->lchild);

  }

}

 

题目2:求二叉树中节点值为x的节点的层数(假设二叉树中的节点的值都不同)。

题解:采用递归算法,设计函数Level(b,x,h),其返回值为在二叉树b中节点值x的节点所在的层次,返回0时表示未找到。h表示b所指节点的层次,从根节点开始查找,根节点的层次为1,所以h的初值为1

int Level(BTNode * b, ElemType x, int h)    //h的初始值为1

{

  if(b == NULL)

  {

    return 0;

  }

  else if(b->data == x)

  {

    return h;

  }else

  {

    int level = Level(b->lchild, x, h+1);

    if(level != 0)

      return level;

    else

      return Level(b->rchild, x, h+1);

  }

}

 

题目3:判断两颗二叉树是否相似。所谓二叉树b1b2相似是指b1b2都是空的二叉树;或者b1b2的根节点相似,且左子树和右子树分别相似。不必比较数值,结构一样就是相似。

//相似返回true,不相似返回false

bool Like(BTNode * b1, BTNode * b2)

{

  if(b1 == NULL && b2 == NULL)

  {

    return true;

  }

  else if(b1 == NULL || b2 == NULL)

  {

    return false;

  }

  else

  {

    bool like1 = Like(b1->lchild, b2->lchild);

    bool like2 = Like(b1->rchild, b2->rchild);

    return (like1 && like2);  

  }

}

题目四:输出值为x的节点的所有的祖先。

//判断b是否时值为x的节点的祖先,如果是,返回true,如果不是,返回false

bool ancestor(BTNode* b, ElemType x)

{

  if(b == NULL)

  {

    return false;

  }

  else if((b->lchild != NULL && b->lchild->data == x) || (b->rchild != NULL && b->rchild->data == x))

  {

    cout<<b->data;

    return true;

  }

  else if(ancestor(b->lchild, x) || ancestor(b->rchild, x))

  {

    cout<<b->data;

    return true;

  }else

  {

    return false;
  }

}

1.3二叉树遍历非递归算法

先序遍历非递归算法

void PreOrder(BTNode *b)

{

  stack<BTNode*> BTStack;

  if(b != NULL)

  {

    BTStack.push(b);

  }

  while(!BTStack.empty())

  {

    BTNode* node = BTStack.top();

    BTStack.pop();

    cout<<node->data;

    if(node->rchild != NULL)

    {

      BTStack.push(node->rchild);

    }

 

    if(node->lchild != NULL)

    {

      BTStack.push(node->lchild);

    }

  } 

  cout<<endl;

}

 

中序遍历非递归算法

void PreOrder(BTNode *b)

{

  stack<BTNode*> BTStack;

  BTNode *node = b;

 

  while(!BTStack.empty() || node != NULL)

  {

    while(node != NULL)

    {

      BTStack.push(node);

      node = node->lchild;

    }

 

    node = BTStack.top();

    BTStack.pop();

    cout<<node->data;

    node = node->rchild;

  } 

  cout<<endl;

}

 

后序遍历非递归算法

 

void PostOrder(BTNode *b)

{

  stack<BTNode *> BTNStack;

  BTNode* p;

  int flag;              //表示是否遍历完成左子树

  if(b != NULL)

  {

    do  

    {

      while(b!= NULL)

      {

        BTNStack.push(b);

        b = b->lchild;

      }

      p = NULL;

      flag = 1;        //表示*b左孩子已访问过或者为空

      while(!BTNStack.empty() && flag)

      {

        b = BTNStack.top();

        if(b->rchild == p)       //查看刚刚遍历过的节点是不是右子树的根节点

        {

          cout<<b->data;

          BTNStack.pop();

          p = b;

        }

        else

        {

          b = b->rchild;

          flag = 0;

        }

      }

    }while(!BTNStack.empty());

    cout<<endl;

  }

}

 

posted on 2022-03-01 08:27  xcxfury001  阅读(133)  评论(0编辑  收藏  举报

导航