【PAT甲级】1115 Counting Nodes in a BST (30分):构造BST+DFS树的遍历

1115 Counting Nodes in a BST (30分)

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than or equal to the node's key.
  • The right subtree of a node contains only nodes with keys greater than the node's key.
  • Both the left and right subtrees must also be binary search trees.

Insert a sequence of numbers into an initially empty binary search tree. Then you are supposed to count the total number of nodes in the lowest 2 levels of the resulting tree.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤1000) which is the size of the input sequence. Then given in the next line are the N integers in [−10001000] which are supposed to be inserted into an initially empty binary search tree.

Output Specification:

For each case, print in one line the numbers of nodes in the lowest 2 levels of the resulting tree in the format:

n1 + n2 = n

      
    

where n1 is the number of nodes in the lowest level, n2 is that of the level above, and n is the sum.

Sample Input:

9
25 30 42 16 20 20 35 -5 28

      
    

Sample Output:

2 + 4 = 6


分析:构造BST+DFS树的遍历

构造BST,计算倒数两层节点的总个数


代码

  • 柳神

    1.一边输入数据一边构造BST,能使代码量变少

    2.不需要记录每个节点的层数,depth作为函数的参数,在DFS遍历时记录num[]和最大深度maxDepth,最后得到num[maxDepth-1]和num[maxDepth-2]即可。

    3.注意最后一层是maxDepth-1,因为比较depth和maxDepth谁更大时的depth比实际多+1(此时root==NULL)。

    #include <iostream>
    #include <vector>
    using namespace std;
    struct node {
        int v;
        struct node *left, *right;
    };
    node* build(node *root, int v) {
        if(root == NULL) {
            root = new node();
            root->v = v;
            root->left = root->right = NULL;
        } else if(v <= root->v)
            root->left = build(root->left, v);
        else
            root->right = build(root->right, v);
        return root;
    }
    vector<int> num(1000);
    int maxdepth = -1;
    void dfs(node *root, int depth) {
        if(root == NULL) {
            maxdepth = max(depth, maxdepth);
            return ;
        }
        num[depth]++;
        dfs(root->left, depth + 1);
        dfs(root->right, depth + 1);
    
    }
    int main() {
        int n, t;
        scanf("%d", &n);
        node *root = NULL;
        for(int i = 0; i < n; i++) {
            scanf("%d", &t);
            root = build(root, t);
        }
        dfs(root, 0);
        printf("%d + %d = %d", num[maxdepth-1], num[maxdepth-2], num[maxdepth-1] + num[maxdepth-2]);
        return 0;
    }


  • 我的做法(不太简洁)

    /*构造BST,计算倒数两层节点的总个数*/
    
    #include<iostream>
    
    using namespace std;
    
    const int maxN=1010;
    struct node {
      int dt;//数据
      int layer;//所在层数
      node* lchild;
      node* rchild;
    };
    int num[maxN];//记录每层节点的个数
    int maxLayer=-1;//节点的最深层数
    int N;
    
    /*构造树*/
    //创建新节点
    node* newNode(int d) {
      node* Node=new node;//申请一个node型变量的地址空间
      Node->dt=d;
      Node->lchild=NULL;
      Node->rchild=NULL;
    
      return Node;
    }
    //插入节点
    void insert(node* &root,int d) {
      if(root==NULL) {//若某个节点没有左、右孩子,则将data作为它的孩子
          root=newNode(d);
          return;
      }
      if(d<=root->dt) { //去左子树
          insert(root->lchild,d);
      } else//去右子树
          insert(root->rchild,d);
    
    }
    //构造BST
    node* create(int data[],int n) {//data节点数据,n节点个数
      node* root=newNode(data[0]);//创建根节点
    
      for(int i=1; i<n; i++) {//根节点已经创建了,从1开始!
          insert(root,data[i]);
      }
    
      return root;
    }
    
    /*DFS遍历树,记录每个节点层数和每层节点个数*/
    void DFS(node* root) {
      if(root->layer>maxLayer)
          maxLayer= root->layer;
    
      num[root->layer]++;
      if(root->lchild!=NULL) {
          root->lchild->layer=root->layer+1;
          DFS(root->lchild);
      }
      if(root->rchild!=NULL) {
          root->rchild->layer=root->layer+1;
          DFS(root->rchild);
      }
    }
    
    int main() {
      fill(num,num+maxN,0);
      scanf("%d",&N);
      int data[N];
      for(int i=0; i<N; i++) {
          scanf("%d",&data[i]);
      }
    
      node* root=create(data,N);
      root->layer=0;//根节点层数为0
      DFS(root);
    
      printf("%d + %d = %d",num[maxLayer],num[maxLayer-1],num[maxLayer]+num[maxLayer-1]);
    }


小知识

  • (与本题无关)有关结构体struct:

    • 定义结构体时,不能定义自身类型的变量(会导致循环定义),但可以定义自身类型的指针变量。
    • 另外声明结构体变量的两种方法
    #include<iostream>
    
    using namespace std;
    
    struct node {
      int data;
      node* child;//不能定义node,但可以定义node*
    };
    
    int main() {
      /*方一*/
      node* childN=new node();
      childN->data=2;
      cout<<childN->data<<endl;
    
      /*方二*/
    //    struct node childN;
    //    childN.data=2;
    //    cout<<childN.data<<endl;
    
      return 0;
    }
  • 选择更大的数并返回:max(x,y)

  • Java里有NULLnull,C++里只有NULL!!


备错本

  • [1115 Counting Nodes in a BST:LIU]

    • build函数内,为root声明变量地址root =new node();,不需要node* root =new node();,这样是重新声明另一个变量。

      node* build(node* &root,int v) {
          if(root==NULL) {
              root =new node();//声明节点变量
              root->data=v;
              root->lchild=root->rchild=NULL;
          } else if(v<=root->data) { //左子树
              root->lchild=build(root->lchild,v);
          } else { //右子树
              root->rchild=build(root->rchild,v);
          }
      
          return root;
      }
      //main函数
      node* root=NULL;
      for(int i=0; i<N; i++) {
          scanf("%d",&v);
          root=build(root,v);
      }


  • [1115 Counting Nodes in a BST:我的做法]

    • create()先创建根节点,之后循环插入其他节点时,注意data[]下标是从1开始的。我错写成从0开始,结果在root=25的左孩子又插入了一边25。

      //插入节点
      void insert(node* &root,int d) {
          if(root==NULL) {//若某个节点没有左、右孩子,则将data作为它的孩子
              root=newNode(d);
              return;
          }
          if(d<=root->dt) { //去左子树
              insert(root->lchild,d);
          } else//去右子树
              insert(root->rchild,d);
      
      }
      //构造BST
      node* create(int data[],int n) {//data节点数据,n节点个数
          node* root=newNode(data[0]);//创建根节点
      //  cout<<"root.data="<<root->dt<<endl;
          if(root==NULL) {
              cout<<"root是空的"<<endl;
          }
      
          for(int i=1; i<n; i++) {//根节点已经创建了,从1开始! 
              insert(root,data[i]);
          }
      
          return root;
      }

猜你喜欢

转载自www.cnblogs.com/musecho/p/12322065.html