二叉樹常見面試題彙總(改進版)
阿新 • • 發佈:2019-02-10
#include <iostream> #include <stack> #include <queue> #include <vector> using namespace std; struct treeNode { int data; treeNode *lson; treeNode *rson; }; bool insert(treeNode *&root,int val)//插入值 { treeNode *p = new treeNode; p->data = val; p->lson = NULL; p->rson = NULL; if (root == NULL) { root = p; return true; } if (root->data == val) return false; if (root->data < val) insert(root->rson, val); else insert(root->lson, val); } void preOrder(treeNode *root) { if (root != NULL) { cout << root->data<<" "; preOrder(root->lson); preOrder(root->rson); } } void display1(treeNode *root)//非遞迴前序遍歷 { stack<treeNode* > s; treeNode *p = root; while (p!=NULL ||!s.empty()) { while (p != NULL) { cout << p->data << " "; s.push(p); p = p->lson; } if (!s.empty()) { p = s.top(); s.pop(); p = p->rson; } } } void inOrder(treeNode *root) { if (root != NULL) { inOrder(root->lson); cout << root->data << " "; inOrder(root->rson); } } void display2(treeNode *root)//非遞迴中序遍歷 { stack<treeNode *> s; treeNode *p = root; while (p != NULL || !s.empty()) { while (p != NULL) { s.push(p); p = p->lson; } if (!s.empty()) { p = s.top(); s.pop(); cout << p->data << " "; p = p->rson; } } } void postOrder(treeNode *root) { if (root != NULL) { postOrder(root->lson); postOrder(root->rson); cout << root->data << " "; } } void display3(treeNode *root) { stack<pair<treeNode *, bool>> s; treeNode *p = root; pair<treeNode *, bool>temp; while (p != NULL || !s.empty()) { while (p != NULL) { s.push(make_pair(p, true));//true表示沒有被訪問 p = p->lson; } if (!s.empty()) { temp = s.top(); s.pop(); if (temp.second == true) { temp.second = false; s.push(temp); p = (temp.first)->rson; } else { cout << (temp.first)->data << " "; p = NULL;//(這句貌似可以不用) } } } } void display4(treeNode* root)//廣度優先 { queue<treeNode *>q; treeNode *p = root; q.push(root); while (!q.empty()) { p = q.front(); q.pop(); cout << p->data; if(p->lson!=NULL) q.push(p->lson); if(p->rson!=NULL) q.push(p->rson); } } void display41(treeNode *root)//按行列印 { queue<treeNode *> q; q.push(root); int total = 0;//下一行的個數 int cost = 1;//本行還有幾個沒有列印 while (!q.empty()) { treeNode *p=q.front(); q.pop(); cout << p->data<<" "; cost--; if (p->lson != NULL) { q.push(p->lson); total++; } if (p->rson != NULL) { q.push(p->rson); total++; } if (cost == 0) { cout << endl; cost = total; total = 0; } } } bool hasSubTree1(treeNode *root1, treeNode *root2) { if (root2 == NULL) return true; if (root1 == NULL) return false; if (root1->data != root2->data) return false; return hasSubTree1(root1->lson, root2->lson) && hasSubTree1(root1->rson, root2->rson); } bool hasSubTree(treeNode *root1, treeNode *root2)//兩棵二叉樹A和B,判斷B是不是A的子結構 { bool result = false; if (root1 != NULL &&root2 != NULL) { if (root1->data == root2->data) { result = hasSubTree1(root1, root2); } if (!result) result = hasSubTree(root1->lson,root2); if (!result) result = hasSubTree(root1->rson, root2); } return result; } //二叉樹映象 void mirror(treeNode *root) { if (root == NULL) return; if (root->lson == NULL &&root->rson == NULL) return; treeNode *temp = root->lson; root->lson = root->rson; root->rson = temp; if (root->lson) mirror(root->lson); if (root->rson)mirror(root->rson); } //判斷是否對稱二叉樹 bool isSymmetrical(treeNode *root1, treeNode *root2) { if (root1 == NULL &&root2 == NULL) return true; if (root1 == NULL || root2 == NULL)return false; if (root1->data != root2->data)return false; return isSymmetrical(root1->lson, root2->rson) && isSymmetrical(root1->rson, root2->lson); } //二叉樹轉換為雙向連結串列 void convertNode(treeNode *root, treeNode *&lastNode) { if (root->lson != NULL) convertNode(root->lson, lastNode); root->lson = lastNode; if (lastNode != NULL) lastNode->rson = root; lastNode = root; if (root->rson != NULL) convertNode(root->rson, lastNode); } treeNode* treeToList(treeNode *root) { treeNode *head = root; while (head->lson)head = head->lson; treeNode *p = NULL; convertNode(root, p); return head; } bool isSymmetrical(treeNode *root) { return isSymmetrical(root, root); } void findPath(treeNode *root, int expectValue, vector<int>&path, int currentSum) { currentSum += root->data; path.push_back(root->data); bool isLeaf = root->lson == NULL && root->rson == NULL; if (isLeaf&¤tSum == expectValue) { cout << "path has been found"<<endl; for (vector<int>::iterator it = path.begin(); it != path.end(); it++) cout << *it << " "; cout << endl; } if (root->lson != NULL) findPath(root->lson, expectValue, path, currentSum); if (root->rson != NULL) findPath(root->rson, expectValue, path, currentSum); path.pop_back(); } void findPath(treeNode *root, int expectValue)//二叉樹中和為某個值的路徑 { if (root == NULL) return; vector<int>path; int currentSum = 0; findPath(root, expectValue, path, currentSum); } //二叉樹的深度 int treeDeep(treeNode *root) { if (root == NULL) return 0; int left = treeDeep(root->lson); int right = treeDeep(root->rson); return (left > right) ? left + 1 : right + 1; } //判斷是否為平衡樹 bool isBalanced(treeNode *root, int &deep) { if (root == NULL) { deep = 0; return true; } int left, right; if (isBalanced(root->lson, left) && isBalanced(root->rson, right)) { int diff = left - right; if (diff <= 1 && diff >= -1) { deep = (left > right) ? 1 + left : 1 + right; return true; } } return false; } bool isBalanced(treeNode *root)//入口 { int deep = 0; return isBalanced(root, deep); } //找到二叉搜尋樹第k個結點(find 和found兩個方法) treeNode* find(treeNode *root, int &k) { treeNode *target = NULL; if (root->lson != NULL) target = find(root->lson, k); if (target == NULL) { if (k == 1) target = root; k--; } if (target == NULL && root->rson != NULL) target = find(root->rson, k); return target; } treeNode *found(treeNode *root, int &k) { treeNode *ans = NULL; if (root != NULL) { ans=found(root->lson, k); k--; if (k == 0) { ans = root; } if(ans==NULL) ans=found(root->rson, k); } return ans; } void main() { treeNode* root = NULL; insert(root, 6); insert(root, 2); insert(root, 7); insert(root, 1); insert(root, 4); insert(root, 3); int n = 6; treeNode *p = treeToList(root); while (p != NULL) { cout << p->data << endl; p = p->rson; } system("pause"); }