1、给出一棵树结构和一组值,把这些值填入树中构成BST(唯一) 2、输出其层序遍历! 3、节点编号 0 ~ N-1,0号为根
方法一: (推荐) 由于BST的中序遍历序列为递增序列,所以把所给值递增排序后,中序遍历插入二叉树结构中;
方法二: 先后序遍历获得每个结点左右子树的结点数,对值序列进行切分,并赋值
| 解题思路 存储结构:树的静态存储! 1、所给值 先排序 2、需要知道左右子树包含的结点个数,进而切分 值序列。 3、如何知道左右子树结点数? 结点结构体增加一个变量记录子结点数量,后序遍历赋值
/********************************** *@ID: 3stone *@ACM: PAT.A1099 Build A Binary Search Tree *@Time: 18/8/16 *@IDE: VSCode 2018 + clang++ ***********************************/ #include<cstdio> #include<algorithm> #include<queue> #include<cmath> #include<cstring> using namespace std; const int maxn = 110; struct node{ //数结点 int data; int nodes_num; int lchild; int rchild; }Node[maxn]; bool flag; //在建树过程中 标记是否能成功 int seq[maxn]; //保存输入的前序序列 int N; //结点数 //建立正常BST void create(int root, int left, int right) { if(root == -1) return; int lchild_num = Node[Node[root].lchild].nodes_num; //左子树的结点数 int root_key = left + lchild_num; //切分 Node[root].data = seq[root_key]; //赋值 //递归 建树 create(Node[root].lchild, left, left + lchild_num - 1); create(Node[root].rchild, left +lchild_num + 1, right); } void BFS_traversal() { queue<int> Q; Q.push(0); int num = 0; while(!Q.empty()) { int front = Q.front(); Q.pop(); num++; if(num == N) printf("%d\n", Node[front].data); else printf("%d ", Node[front].data); if(Node[front].lchild != -1) Q.push(Node[front].lchild); if(Node[front].rchild != -1) Q.push(Node[front].rchild); } } //后序遍历 (回溯赋值每个结点左右子树所含的结点数) int post_traversal(int v) { if(v == -1) return 0; int lchild_num = post_traversal(Node[v].lchild); int rchild_num = post_traversal(Node[v].rchild); Node[v].nodes_num = lchild_num + rchild_num + 1; return Node[v].nodes_num; } int main() { while(scanf("%d", &N) != EOF) { //input BST structure for(int i = 0; i < N; i++){ scanf("%d%d", &Node[i].lchild, &Node[i].rchild); } //input seq[] for(int i = 0; i < N; i++) scanf("%d", &seq[i]); //后序遍历 (回溯赋值每个结点左右子树所含的结点数) post_traversal(0); // the key of root = 0 sort(seq, seq + N); //待插入值先排序 create(0, 0, N - 1); BFS_traversal(); } return 0; }