PAT (Advanced Level) Practice 二叉樹 相關題node
struct Node{ typename data; int level; int lchild; int rchild; } node[MAXN];
int index = 0; int newNode (int value){ node[index].data = value; node->lchild = node->rchild = -1; return index++; }
void insert (int &root, int value){ if (root == -1){ root = newNode(value); return; } if (由二叉樹性質應插入在左子樹) insert(node[root].lchild, value); else insert(node[root].rchild, value); }
int create(int value[], int n){ int root = -1; for (int i = 0; i < n; i++) insert(root, data[i]); return root; }
void search (int root, int value, int newvalue){ if (root == -1) return; if (node[root].data == value) node[root].data = newvalue; search(node[root].lchild, value, newvalue); search(node[root].rchild, value, newvalue); }
void preorder(int root){ if (root == -1) return; printf("%d\n", node[root].data); preorder(node[root].lchild); preorder(node[root].rchild); }
void inorder(int root){ if (root == -1) return; preorder(node[root].lchild); printf("%d\n", node[root].data); preorder(node[root].rchild); }
void postorder(int root){ if (root == -1) return; preorder(node[root].lchild); preorder(node[root].rchild); printf("%d\n", node[root].data); }
void levelorder(int root){ queue<int> q; q.push(root); while (!q.empty()){ int now = q.front(); q.pop(); printf("%d", node[now].data); if (node[now].lchild != -1) q.push(node[now].lchild); if (node[now].rchild != -1) q.push(node[now].rchild); } }
int create (int preL, int preR, int inL, int inR){ if (preL > preR) return -1; int root = new Node(pre[preL]); int k; for (k = inL; k <= inR; k++) if (in[k] == pre[preL]) break; int numLeft = k - inL; // 左子樹結點個數 node[root].lchild = create(preL+1, preL+numLeft, inL, k-1); node[root].rchild = create(preL+numLeft+1, preR, k+1, inR); return root; }
#include<iostream> #include<vector> using namespace std; int post[31], in[31]; vector<int> pre; void preorder(int post_root, int inL, int inR) { if (inL > inR) return; pre.push_back(post[post_root]); int k; for (k = inL; k <= inR; k++) if (in[k] == post[post_root]) break; preorder(post_root-1-inR+k, inL, k-1); preorder(post_root-1, k+1, inR); } int main() { int n; scanf("%d",&n); for (int i = 0; i < n; i++) scanf("%d", post+i); for (int i = 0; i < n; i++) scanf("%d", in+i); preorder(n-1, 0, n-1); printf("%d",pre[0]); for (int i = 1; i < pre.size(); i++) printf(" %d",pre[i]); return 0; }
#include<iostream> #include<vector> #include<algorithm> using namespace std; struct Node{ int index, value; }; bool cmp (Node a, Node b){ return a.index < b.index; } int post[31], in[31]; vector<Node> level; void levelorder(int post_root, int inL, int inR, int index) { if (inL > inR) return; level.push_back({index,post[post_root]}); int k; for (k = inL; k <= inR; k++) if (in[k] == post[post_root]) break; levelorder(post_root-1-inR+k, inL, k-1, 2 * index); levelorder(post_root-1, k+1, inR, 2 * index + 1); } int main() { int n; scanf("%d",&n); for (int i = 0; i < n; i++) scanf("%d", post+i); for (int i = 0; i < n; i++) scanf("%d", in+i); levelorder(n-1, 0, n-1, 1); sort(level.begin(),level.end(),cmp); printf("%d",level[0].value); for (int i = 1; i < level.size(); i++) printf(" %d",level[i].value); return 0; }
#include<iostream> #include<queue> #include<vector> using namespace std; struct Node{ int data, lchild, rchild; } node[31]; int index = 0; int post[31], in[31]; int newNode(int value) { node[index].data = value; node[index].lchild = node[index].rchild = -1; return index++; } int build(int postL, int postR, int inL, int inR) { if (postL > postR) return -1; int root = newNode(post[postR]); int k; for (k = inL; k <= inR; k++) if (in[k] == post[postR]) break; int leftnum = k - inL; node[root].lchild = build(postL, postL+leftnum-1, inL, k-1); node[root].rchild = build(postL+leftnum, postR-1, k+1, inR); return root; } void levelorder(int root){ queue<int> q; q.push(root); vector<int> result; while(!q.empty()){ int now = q.front(); q.pop(); result.push_back(now); if (node[now].lchild != -1) q.push(node[now].lchild); if (node[now].rchild != -1) q.push(node[now].rchild); } printf("%d", node[result[0]].data); for (int i = 1; i < result.size(); i++) printf(" %d", node[result[i]].data); } int main() { int n; scanf("%d",&n); for (int i = 0; i < n; i++) scanf("%d", post+i); for (int i = 0; i < n; i++) scanf("%d", in+i); int root = build(0, n-1, 0, n-1); levelorder(root); return 0; }
#include<iostream> #include<vector> #include<stack> using namespace std; vector<int> in, pre, post; void postorder(int preroot, int inL, int inR){ if (inL > inR) return; int k; for (k = inL; k <= inR; k++) if (in[k] == pre[preroot]) break; postorder(preroot+1, inL, k-1); postorder(preroot+k-inL+1, k+1, inR); post.push_back(pre[preroot]); } int main() { int n, num; scanf("%d", &n); string op; stack<int> s; for (int i = 0; i < 2 * n; i++){ cin >> op; if (op.length() > 3){ scanf("%d", &num); pre.push_back(num); s.push(num); } else{ in.push_back(s.top()); s.pop(); } } postorder(0, 0, n-1); for (int i = 0; i < n; i++) printf("%d%c", post[i], i == n - 1 ? '\n' : ' '); return 0; }
#include<iostream> #include<vector> #include<queue> using namespace std; vector<pair<int,int>> node; vector<int> level, in; void levelorder(int root) { queue<int> q; q.push(root); while (!q.empty()){ int now = q.front(); level.push_back(now); q.pop(); if (node[now].first != -1) q.push(node[now].first); if (node[now].second != -1) q.push(node[now].second); } } void inorder(int root) { if (root == -1) return; inorder(node[root].first); in.push_back(root); inorder(node[root].second); } int main() { int n; scanf("%d",&n); char a, b; getchar(); bool appear[n] = {false}; for (int i = 0; i < n; i++){ scanf("%c %c", &a, &b); getchar(); if (a != '-') appear[a-'0'] = true; if (b != '-') appear[b-'0'] = true; a = a == '-' ? -1 : a-'0'; b = b == '-' ? -1 : b-'0'; node.push_back({b,a}); } int root = 0; while (appear[root]) root++; levelorder(root); printf("%d", level[0]); for (int i = 1; i < level.size(); i++) printf(" %d", level[i]); inorder(root); printf("\n%d", in[0]); for (int i = 1; i < in.size(); i++) printf(" %d", in[i]); return 0; }
pre[k] == post[postR-1]
),默認其爲右子樹結點,則其在先序序列中前面的結點即爲左子樹節點numL = k - preL - 1
post[postR-1]
這一點可能在左也可能在右,應置 unique = false
post[postR]
壓入中序序列preL == preR
時說明子樹僅有一個結點,則沒必要進行復雜處理,直接壓入中序序列便可#include<iostream> #include<vector> using namespace std; vector<int> pre, post, in; bool unique = true; void inorder(int preL, int preR, int postL, int postR) { if (preL == preR){ in.push_back(pre[preL]); return; } int k; for (k = preL + 1; k <= preR && pre[k] != post[postR-1]; k++); int numL = k - preL - 1; if (numL > 0) inorder(preL+1, k-1, postL, postL+numL-1); else unique = false; in.push_back(post[postR]); inorder(k, preR, postL+numL, postR-1); } int main() { int n; scanf("%d", &n); pre.resize(n); post.resize(n); for (int i = 0; i < n; i++) scanf("%d", &pre[i]); for (int i = 0; i < n; i++) scanf("%d", &post[i]); inorder(0, n-1, 0, n-1); printf("%s\n", unique ? "Yes" : "No"); for (int i = 0; i < in.size(); i++) printf("%d%c", in[i], i+1 == in.size() ? '\n' : ' '); return 0; }
#include<iostream> #include<vector> using namespace std; vector<int> in, post, leveldata[31]; void leveltrave(int root, int inL, int inR, int level){ if (inL > inR) return; leveldata[level].push_back(post[root]); int k; for (k = inL; k <= inR; k++) if (in[k] == post[root]) break; leveltrave(root-(inR-k)-1, inL, k-1, level+1); leveltrave(root-1, k+1, inR, level+1); } int main() { int n; scanf("%d", &n); in.resize(n); for (int i = 0; i < n; i++) scanf("%d", &in[i]); post.resize(n); for (int i = 0; i < n; i++) scanf("%d", &post[i]); leveltrave(n-1, 0, n-1, 0); printf("%d", leveldata[0][0]); for (int i = 1; i < 31; i++){ if (i % 2) for (int j = 0; j < leveldata[i].size(); j++) printf(" %d",leveldata[i][j]); else for (int j = leveldata[i].size(); j > 0; j--) printf(" %d",leveldata[i][j-1]); } return 0; }
#include<iostream> #include<vector> using namespace std; vector<int> pre, in, post; void postorder(int pre_root, int inL, int inR) { if (inL > inR) return; int k; for (k = inL; k <= inR; k++) if (pre[pre_root] == in[k]) break; postorder(pre_root+1, inL, k-1); postorder(pre_root+1+k-inL, k+1, inR); post.push_back(pre[pre_root]); } int main() { int n, value; scanf("%d",&n); for (int i = 0; i < n; i++){ scanf("%d", &value); pre.push_back(value); } for (int i = 0; i < n; i++){ scanf("%d", &value); in.push_back(value); } postorder(0, 0, n-1); printf("%d", post[0]); return 0; }
#include<iostream> #include<vector> using namespace std; vector<int> pre, in; bool flag = false; void postorder(int pre_root, int inL, int inR) { if (inL > inR || flag) return; int k; for (k = inL; k <= inR; k++) if (pre[pre_root] == in[k]) break; postorder(pre_root+1, inL, k-1); postorder(pre_root+1+k-inL, k+1, inR); if (!flag){ flag = true; printf("%d",pre[pre_root]); } } int main() { int n, value; scanf("%d",&n); for (int i = 0; i < n; i++){ scanf("%d", &value); pre.push_back(value); } for (int i = 0; i < n; i++){ scanf("%d", &value); in.push_back(value); } postorder(0, 0, n-1); return 0; }
#include<iostream> #include<vector> #include<unordered_map> using namespace std; vector<int> pre, in; unordered_map<int,int> inidx; int u, v; void LCA(int root, int inL, int inR){ if (inL > inR) return; int k = inidx[pre[root]], uin = inidx[u], vin = inidx[v]; if (k == uin) printf("%d is an ancestor of %d.\n", u, v); else if (k == vin) printf("%d is an ancestor of %d.\n", v, u); else if (uin < k && vin < k) LCA(root+1, inL, k-1); else if (uin > k && vin > k) LCA(root+k-inL+1, k+1, inR); else printf("LCA of %d and %d is %d.\n", u, v, pre[root]); } int main() { int m, n; scanf("%d%d", &m, &n); in.resize(n); for (int i = 0; i < n; i++){ scanf("%d", &in[i]); inidx[in[i]] = i; } pre.resize(n); for (int i = 0; i < n; i++) scanf("%d", &pre[i]); for (int i = 0; i < m; i++){ scanf("%d%d", &u, &v); if (inidx.find(u) == inidx.end() && inidx.find(v) == inidx.end()) printf("ERROR: %d and %d are not found.\n", u, v); else if (inidx.find(u) == inidx.end()) printf("ERROR: %d is not found.\n", u); else if (inidx.find(v) == inidx.end()) printf("ERROR: %d is not found.\n", v); else LCA(0, 0, n-1); } return 0; }
struct Node{ typename data; int level Node* lchild; Node* rchild; }
Node* newNode (int value){ Node* node = new Node; node->data = value; node->lchild = node->rchild = NULL; return node; }
void insert (Node* &root, int value){ if (root == NULL){ root = newNode(value); return; } if (由二叉樹性質應插入在左子樹) insert(root->lchild, value); else insert(root->rchild, value); }
Node* create(int value[], int n){ node* root = NULL; for (int i = 0; i < n; i++) insert(root, data[i]); return root; }
void search (Node* root, int value, int newvalue){ if (root == NULL) return; if (root->data == value) root->data = newvalue; search(root->lchild, value, newvalue); search(root->rchild, value, newvalue); }
void preorder(Node* root){ if (root == NULL) return; printf("%d\n", root->data); preorder(root->lchild); preorder(root->rchild); }
void inorder(Node* root){ if (root == NULL) return; preorder(root->lchild); printf("%d\n", root->data); preorder(root->rchild); }
void postorder(Node* root){ if (root == NULL) return; preorder(root->lchild); preorder(root->rchild); printf("%d\n", root->data); }
void levelorder(Node* root){ queue<Node*> q; root->level = 1; q.push(root); while (!q.empty()){ Node* now = q.front(); q.pop(); printf("%d", now->data); if (now->lchild != NULL){ now->lchild->level = now->level + 1; q.push(now->lchild); } if (now->rchild != NULL){ now->rchild->level = now->level + 1; q.push(now->rchild); } } }
Node* create (int preL, int preR, int inL, int inR){ if (preL > preR) return NULL; Node* root = new Node; root->data = pre[preL]; int k; for (k = inL; k <= inR; k++) if (in[k] == pre[preL]) break; int numLeft = k - inL; // 左子樹結點個數 root->lchild = create(preL+1, preL+numLeft, inL, k-1); root->rchild = create(preL+numLeft+1, preR, k+1, inR); return root; }