您的位置:首页 > 其它

九度OJ-题目1523:从上往下打印二叉树

2015-06-08 10:49 393 查看
题目链接地址:

九度OJ-题目1523:从上往下打印二叉树

题目描述:

从上往下打印出二叉树的每个节点,同层节点从左至右打印。

输入:

输入可能包含多个测试样例,输入以EOF结束。

对于每个测试案例,输入的第一行一个整数n(1<=n<=1000, :n代表将要输入的二叉树元素的个数(节点从1开始编号)。接下来一行有n个数字,代表第i个二叉树节点的元素的值。接下来有n行,每行有一个字母Ci。

Ci=’d’表示第i个节点有两子孩子,紧接着是左孩子编号和右孩子编号。

Ci=’l’表示第i个节点有一个左孩子,紧接着是左孩子的编号。

Ci=’r’表示第i个节点有一个右孩子,紧接着是右孩子的编号。

Ci=’z’表示第i个节点没有子孩子。

输出:

对应每个测试案例,

按照从上之下,从左至右打印出二叉树节点的值。

样例输入:

7

8 6 5 7 10 9 11

d 2 5

d 3 4

z

z

d 6 7

z

z

样例输出:

8 6 10 5 7 9 11

解题思路:

从上往下打印出二叉树的每个节点,同层节点从左至右打印,很明显这是二叉树的层序遍历。深井冰人思维广,很快我就发现二叉树的层序遍历和图的广度优先遍历很相似啊。于是就模仿图的广度优先遍历想(YY)出了以下算法:

(1) 申请一个队列用于保存二叉树的结点,将二叉树的根结点插入到队列末尾;

(2) 弹出队列的队首元素,如果该元素还有左右孩子,则将其左右孩子也依次插入到队列末尾;

(3) 重复步骤(2),当队列为空时,二叉树的层序遍历操作就完成了。

AC代码如下:

// 二叉树的层序遍历
#include<stdio.h>
#include<queue>
using namespace std;
#define MAX 1001
 
// 定义二叉树的结点
typedef struct Node
{
  bool isRoot;                   // 标记该结点是否为二叉树的根结点
  int data;                      // 数据域
  Node * lchild;                 // 左孩子
  Node * rchild;                 // 右孩子
}BiTreeNode;
 
// 定义二叉树中的各个结点
BiTreeNode biTreeNode[MAX];
 
/**
* 构造有n个结点的二叉树
* @param n  表示二叉树的结点个数
* @return root  返回二叉树的根结点
*/
BiTreeNode * createBinaryTree(int n)
{
  BiTreeNode * root = NULL;
  char Ci;
  int i;
  int data;          // 输入的二叉树结点的数据
  int leftChild;     // 二叉树结点的左孩子编号
  int rightChild;    // 二叉树结点的右孩子编号
  // (1)初始时各个结点都被看成是只有一个结点的二叉树
  for(i = 1;i <= n;i++)
  {
      scanf("%d",&data);
      biTreeNode[i].data = data;
      biTreeNode[i].lchild = NULL;
      biTreeNode[i].rchild = NULL;
      biTreeNode[i].isRoot = true;
  }
  // (2)构建各个结点的孩子
  for(i = 1;i <= n;i++)
  {
     while(getchar() != '\n');               // 清除前一个scanf留下的多余的字符
     scanf("%c",&Ci);
     switch(Ci)
     {
         case 'd':
               scanf("%d%d",&leftChild,&rightChild);
               biTreeNode[i].lchild = &biTreeNode[leftChild];
               biTreeNode[i].rchild = &biTreeNode[rightChild];
               biTreeNode[leftChild].isRoot = false;
               biTreeNode[rightChild].isRoot = false;
               break;
         case 'l':
               scanf("%d",&leftChild);
               biTreeNode[i].lchild = &biTreeNode[leftChild];
               biTreeNode[leftChild].isRoot = false;
               break;
         case 'r':
               scanf("%d",&rightChild);
               biTreeNode[i].rchild = &biTreeNode[rightChild];
               biTreeNode[rightChild].isRoot = false;
               break;
         case 'z':
               break;
         default:
               break;
     }//switch
  }//for
  //(3)寻找二叉树的根结点,如果某个结点没有父结点,则认为该结点是二叉树的根结点
  for(i = 1;i <= n;i++)
  {
      if(true == biTreeNode[i].isRoot)
      {
          root = &biTreeNode[i];
          break;
      }
  }
  return root;
}
 
/**
* 采用类似于广度优先遍历的方法来层序遍历二叉树
* @param root  二叉树的根结点
* @return void
*/
void travLevelBinaryTree(BiTreeNode * root)
{
   BiTreeNode * cur;              // 当前正在被遍历的二叉树结点
   queue <BiTreeNode *> q;
   q.push(root);                  // 将二叉树的根结点插入到队列末尾
   while(false == q.empty())
   {
    cur = q.front();
    q.pop();
    if(cur == root)
    {
       printf("%d",cur -> data);    // 输出当前结点的值
    }
    else
    {
       printf(" %d",cur -> data);    // 输出当前结点的值
    }
 
    if(NULL != cur -> lchild)     // 将当前结点的左孩子插入到队列末尾
    {
        q.push(cur -> lchild);
    }
    if(NULL != cur -> rchild)     // 将当前结点的右孩子插入到队列末尾
    {
        q.push(cur -> rchild);
    }
   }
   printf("\n");
}
 
int main()
{
    BiTreeNode * root;
    int n;
    while(EOF != scanf("%d",&n))
    {
        root = createBinaryTree(n);
        travLevelBinaryTree(root);             // 层序遍历二叉树
    }
    return 0;
}
 
/**************************************************************
    Problem: 1523
    User: blueshell
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1076 kb
****************************************************************/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: