【面試筆試】二叉樹相關操作
阿新 • • 發佈:2019-02-16
// 二叉樹 // 2015.08.07 //@ author :braveji /** 二叉樹的功能 ** 1 建立二叉樹 銷燬二叉樹 ** 2 二叉樹的遍歷:前、中、後,層,分層;遞迴、非遞迴; ** 3 二叉樹的高度、寬度、葉子節點個數 ** 4 將二叉搜尋樹轉換為雙鏈表 ** 5 二叉樹的映象 ** 6 找出和為指定值的所有路徑(後序遍歷) ** 7 是否是平衡二叉樹(左子樹的深度pk右子數的深度) ** 7 相距最遠的兩個節點的距離(左子樹深度+右子樹的深度) ** 8 給定兩個節點求其最近公共父節點 ** 9 判斷是否是完全二叉樹? ** 10 根據前序和中序遍歷重構二叉樹 **/ #include <vector> #include <string> #include <iostream> #include <fstream> #include <queue> #include <stack> using namespace std; //difine Btree struct Btree { int m_data; Btree * m_lchild; Btree * m_rchild; }; // initialization Btree * initBtree() { return NULL; } // build Btree const int edge = 65535; fstream fin("init.txt"); int data; void buildBtree(Btree* &root,fstream &fin) { if(fin >> data) { //preorder build Btree if (data == edge) { root = NULL; } else { root = new Btree; root->m_data = data; root->m_lchild = NULL; root->m_rchild = NULL; buildBtree(root->m_lchild,fin); buildBtree(root->m_rchild,fin); } } } Btree * buildBtree() { Btree * root = initBtree(); buildBtree(root,fin); fin.close(); return root; } //traverse tree //1 preorder recursion void preOrderBtree(Btree * root,vector<int> & vectorTemp) { if (root) { cout<<root->m_data<<" "; vectorTemp.push_back(root->m_data); preOrderBtree(root->m_lchild,vectorTemp); preOrderBtree(root->m_rchild,vectorTemp); } } vector<int> preOrderBtree(Btree * root) { // if (root) // { // cout<<root->m_data<<" "; // preOrderBtree(root->m_lchild); // preOrderBtree(root->m_rchild); // } vector<int> vectorTemp; preOrderBtree(root,vectorTemp); return vectorTemp; } //2 inorder recursion void inOrderBtree(Btree * root,vector<int> & vectorTemp) { if (root) { inOrderBtree(root->m_lchild,vectorTemp); cout<<root->m_data<<" "; vectorTemp.push_back(root->m_data); inOrderBtree(root->m_rchild,vectorTemp); } } vector<int> inOrderBtree(Btree * root) { // if (root) // { // inOrderBtree(root->m_lchild); // cout<<root->m_data<<" "; // inOrderBtree(root->m_rchild); // } vector<int> vectorTemp; inOrderBtree(root,vectorTemp); return vectorTemp; } //3 postorder recursion void postOrderBtree(Btree *root) { if (root) { postOrderBtree(root->m_lchild); postOrderBtree(root->m_rchild); cout<<root->m_data<<" "; } } // 4 level order void leverOrderBtree(Btree * root) { queue<Btree*> que; if (root) { que.push(root); while(que.size()) { Btree * temp = que.front(); cout<<temp->m_data<<ends; que.pop(); if (temp->m_lchild) que.push(temp->m_lchild); if (temp->m_rchild) que.push(temp->m_rchild); } cout<<endl; } } // multi lever order void multiLeverOrderBtree(Btree * root) { queue<Btree*> que; int nextLever=0,toBePrinted=1;//只有上一層遍歷完才知道下一層總共有多少個結點需要遍歷 int i=1; if (root) { que.push(root); //cout<<"第"<<i<<"層:"; while(que.size()) { Btree * temp = que.front(); cout<<temp->m_data<<ends; que.pop(); toBePrinted--; if (temp->m_lchild) { que.push(temp->m_lchild); nextLever++; } if (temp->m_rchild) { que.push(temp->m_rchild); nextLever++; } if (!toBePrinted) { toBePrinted = nextLever; nextLever =0; ++i; cout<<endl; //cout<<"第"<<i+1<<"層:"; } } } } //preorder nonrecursion void preOrderNonrecurion(Btree * root) { stack<Btree *> stackTemp; while(root || stackTemp.size()) { if (root) { cout<<root->m_data<<ends; stackTemp.push(root); root = root->m_lchild; } else { Btree * temp = stackTemp.top(); stackTemp.pop(); root = temp->m_rchild; } } cout<<endl; } //inorder nonrecursion void inOrderNonrecursion(Btree * root) { stack<Btree *> stackTemp; while(root || stackTemp.size()) { if (root) { stackTemp.push(root); root = root->m_lchild; } else { Btree * temp = stackTemp.top(); stackTemp.pop(); cout<<temp->m_data<<ends; root = temp->m_rchild; } } cout<<endl; } //postorder unrecursion void postOrderRecursion(Btree * root) { stack<Btree *> stackTemp; if (root) stackTemp.push(root); Btree * cur; Btree * prev = NULL; while(stackTemp.size()) { cur = stackTemp.top(); if ((!cur->m_lchild && !cur->m_rchild)|| (prev &&(prev == cur->m_lchild || prev == cur->m_rchild))) { cout<<cur->m_data<<ends; stackTemp.pop(); prev = cur; } else { if (cur->m_rchild) stackTemp.push(cur->m_rchild); if (cur->m_lchild) stackTemp.push(cur->m_lchild); } } cout<<endl; } //deepth int deepthBtree(Btree * root) { if (!root) return 0; int i = deepthBtree(root->m_lchild); int j = deepthBtree(root->m_rchild); return i>j?i+1:j+1; } //leaf number int leafNumber(Btree * root) { //traverse + leaf int leafNum=0; stack<Btree *> stackTemp; while(root || stackTemp.size()) { while (root) { if (!root->m_lchild && !root->m_rchild) leafNum++; stackTemp.push(root); root = root->m_lchild; } if(stackTemp.size()) { Btree * temp = stackTemp.top(); stackTemp.pop(); root = temp->m_rchild; } } return leafNum; } //width BTree int widthBtree(Btree * root) { int maxWidth=0; int toBeDone =1; int count =0; queue<Btree*> que; if(root) que.push(root); while(que.size()) { Btree * temp = que.front(); que.pop(); if (temp->m_lchild) { que.push(temp->m_lchild); count++; } if (temp->m_rchild) { que.push(temp->m_rchild); count++; } toBeDone--; if (!toBeDone) { toBeDone = count; if (count > maxWidth) maxWidth = count; count=0; } } return maxWidth; } //i th level print void printILevel(Btree * root,int i) { int deep = deepthBtree(root); if (i>deep) { cout<<"error!!列印的行數超過了樹的深度!!"<<endl; return; } queue<Btree *> que; int toBeDone =1; int nextLevelNum =0; int level = 1; if (root) que.push(root); cout<<"只打印第"<<i<<"層: "; while(que.size()) { Btree * temp = que.front(); if (i==level) cout<<temp->m_data<<ends; if (i+1==level) break; que.pop(); if (temp->m_lchild) { que.push(temp->m_lchild); nextLevelNum++; } if (temp->m_rchild) { que.push(temp->m_rchild); nextLevelNum++; } toBeDone--; if (!toBeDone) { toBeDone = nextLevelNum; nextLevelNum =0; level++; } } cout<<endl; } //mirror tree Btree* mirrorBtree(Btree * root) { if (root) { Btree * temp = root->m_lchild; root->m_lchild = root->m_rchild; root->m_rchild = temp; if (root->m_lchild) mirrorBtree(root->m_lchild); if (root->m_rchild) mirrorBtree(root->m_rchild); } return root; } //deepth nonrecursion int deepthNonRecursion(Btree * root) { //levle order int toBeDone =1; int nextLevel =0; int deep =0; queue<Btree*> que; if (root) que.push(root); while(que.size()) { Btree * temp = que.front(); que.pop(); if (temp->m_lchild) { que.push(temp->m_lchild); nextLevel++; } if (temp->m_rchild) { que.push(temp->m_rchild); nextLevel++; } toBeDone--; if (!toBeDone) { deep++; toBeDone = nextLevel; nextLevel =0; } } return deep; } //balanced Btree //bool isBalancedBtree(Btree * root) //{ // if (!root) // return true; // int i = deepthBtree(root->m_lchild); // int j = deepthBtree(root->m_rchild); // if (abs(i-j)>1) // return false; // else // return isBalancedBtree(root->m_lchild) && isBalancedBtree(root->m_rchild); //} //測試集1:平衡樹 10 6 3 2 65535 65535 4 65535 65535 8 7 65535 65535 9 65535 65535 20 15 12 65535 65535 17 65535 65535 25 22 65535 65535 30 65535 65535 //測試集2:非平衡 10 6 3 2 65535 65535 4 65535 65535 8 7 65535 65535 9 65535 65535 20 65535 65535 bool isBalancedBtree(Btree* root) { stack<Btree*> stackTemp; while(root || stackTemp.size()) { while(root) { int i= deepthBtree(root->m_lchild); int j = deepthBtree(root->m_rchild); if (abs(i-j)>1) return false; //if (root->m_lchild) // stackTemp.push(root->m_lchild);//錯誤原因:加了條件判斷 stackTemp.push(root); root = root->m_lchild; } if (stackTemp.size()) { Btree * temp = stackTemp.top(); stackTemp.pop(); root = temp->m_rchild; } } return true; } //lowest parent Binary Search Tree Btree * lowestParent(Btree * root,Btree* node1,Btree* node2) { if ((root->m_data >= node1->m_data && root->m_data <= node2->m_data) || (root->m_data <= node1->m_data && root->m_data >= node2->m_data)) { return root; } if (root->m_data < node1->m_data && root->m_data < node2->m_data) return lowestParent(root->m_rchild,node1,node2); else return lowestParent(root->m_lchild,node1,node2); } //10 6 3 2 65535 65535 4 65535 65535 8 7 65535 65535 9 65535 65535 20 15 12 65535 65535 17 65535 65535 25 22 65535 65535 30 65535 65535 //convert to doublelinklist // 10 6 3 65535 65535 8 65535 65535 20 15 65535 65535 25 65535 65535 void conver2list(Btree* root,Btree * &prev,Btree * &head,Btree * & last) {//root 沒有引用,prev有引用, if (root) { //last = root; if (root->m_lchild) conver2list(root->m_lchild,prev,head,last); root->m_lchild = prev;//修改了root if (prev) prev->m_rchild = root; prev = root; if (!head) head = root; if (root->m_rchild) conver2list(root->m_rchild,prev,head,last); } // if (root->m_lchild) // conver2list(root->m_lchild,prev,head); // // root->m_lchild = prev; // if (prev) // prev->m_rchild = root; // prev = root; // if (!head) // head = root; // // if (root->m_rchild) // conver2list(root->m_rchild,prev,head); } Btree * conver2list(Btree* root) { Btree * prev = NULL; Btree * head = NULL; Btree * last = NULL; //if (root) conver2list(root,prev,head,last); return head; } // convert to list nonconversion Btree * convert2ListNonrecursion(Btree * root) { //inorder Btree * prev = NULL; Btree * head = NULL; stack<Btree *> stackTemp; while(root || stackTemp.size()) { while(root) { stackTemp.push(root); root = root->m_lchild; } if (stackTemp.size()) { Btree * curr = stackTemp.top(); stackTemp.pop(); curr->m_lchild = prev; if (prev) prev->m_rchild = curr; prev = curr; if (!head) head = curr; //if (curr->m_rchild) root = curr->m_rchild; root = curr->m_rchild; } } return head; } void printConverList(Btree * root) { cout<<"從小到大:"<<ends; Btree * temp; while(root) { temp= root; cout<<root->m_data<<" "; root = root->m_rchild; } cout<<endl<<"從大到下:"<<ends; while(temp) { cout<<temp->m_data<<" "; temp = temp->m_lchild; } cout<<endl; } //destroy list void destroyList(Btree * head) { Btree * next = head; while(head) { next = head->m_rchild; delete head; head = NULL; head = next; } } //和為指定值的所有路徑 //指定結點的路徑(根到結點的路徑) bool pathToNode(Btree * root,Btree * node,vector<Btree *> & stackTemp) { //preorder if (!root) return false; stackTemp.push_back(root); if (root == node) return true; bool found = pathToNode(root->m_lchild,node,stackTemp); if (!found) found = pathToNode(root->m_rchild,node,stackTemp); if (!found) stackTemp.pop_back(); return found; } //找到值為某一值的結點 Btree * findNodeKey(Btree * root,int num) { //front order stack<Btree *> stackTemp; while(root || stackTemp.size()) { while(root) { stackTemp.push(root); if (root->m_data == num) { return root; } root = root->m_lchild; } if (stackTemp.size()) { Btree * temp = stackTemp.top(); stackTemp.pop(); root = temp->m_rchild; } } return NULL; } // 非遞迴 兩個結點的最低公共祖先 Btree* lowestParentNorecursion(Btree * root,Btree * node1,Btree * node2) { vector<Btree *> temp1,temp2; pathToNode(root,node1,temp1); pathToNode(root,node2,temp2); int i= temp1.size(); int j =temp2.size(); int k=0; Btree * parent= root; while(k<i && k<j) { if (temp2[k] == temp1[k]) { parent = temp1[k]; k++; } else break; } return parent; } //葉子節點的所有路徑 void pathEqualValue(Btree* root,vector<vector<Btree*>> &vectorTemp,vector<Btree*> &temp) { if (!root) return ; temp.push_back(root); if (!root->m_lchild && !root->m_rchild) { vectorTemp.push_back(temp); temp.pop_back(); // root = temp[temp.size()-1]->m_rchild; // pathEqualValue(root,num,vectorTemp,temp); return ; } //if(root->m_lchild) pathEqualValue(root->m_lchild,vectorTemp,temp); //if (root->m_rchild) pathEqualValue(root->m_rchild,vectorTemp,temp); temp.pop_back(); // if (!temp.size()) // { // return ; // } } //等於給定值的所有路徑 void pathEqualValue(Btree* root,int num,int sum,vector<vector<Btree*>> &vectorTemp,vector<Btree*> &temp) { //preorder if (!root) return; sum+= root->m_data; temp.push_back(root); if (!root->m_lchild && !root->m_rchild) { if (sum == num) { vectorTemp.push_back(temp); temp.pop_back(); sum -= root->m_data; return; } } pathEqualValue(root->m_lchild,num,sum,vectorTemp,temp); pathEqualValue(root->m_rchild,num,sum,vectorTemp,temp); temp.pop_back(); sum -= root->m_data; } void pathEqualValue(Btree* root,int num) { vector<vector<Btree*> > vectorTemp,vectorTemp1; vector<Btree*> temp,temp1; pathEqualValue(root,vectorTemp,temp); cout<<"所有葉子節點的路徑:"<<endl; for (unsigned i=0;i<vectorTemp.size();++i) { temp = vectorTemp[i]; for (unsigned j=0;j<temp.size();++j) { cout<<temp[j]->m_data<<" "; } cout<<endl; } pathEqualValue(root,num,0,vectorTemp1,temp1); cout<<"所有值為"<<num<<"的路徑:"<<endl; for (unsigned i=0;i<vectorTemp1.size();++i) { temp = vectorTemp1[i]; for (unsigned j=0;j<temp.size();++j) { cout<<temp[j]->m_data<<" "; } cout<<endl; } } //結點最大距離 int maxLengthBtree(Btree * root) { if (!root) return 0; int i = deepthBtree(root->m_lchild); int j = deepthBtree(root->m_rchild); return i+j; } //根據前序遍歷和中序遍歷重構一棵樹 Btree * rebuild(vector<int> &preorder,vector<int> &inorder,int preleft,int preright,int inleft,int inright) { if (preright-preleft<0) { return NULL; } Btree * root = new Btree; root->m_data = preorder[preleft]; root->m_lchild = NULL; root ->m_rchild = NULL; int middle =-1; for (unsigned i=0;i<inorder.size();++i) { if (root->m_data == inorder[i]) { middle = i; break; } } int d = middle-inleft; int preleft1 = preleft +1; //int preright1 = middle; int preright1 = preleft +d; int inleft1 = inleft; int inright1 = middle-1; root->m_lchild = rebuild(preorder,inorder,preleft1,preright1,inleft1,inright1); //int preleft2 = middle+1; int preleft2 = preleft +d+1; int preright2 = preright; int inleft2 = middle+1; int inright2 = inright; root->m_rchild = rebuild(preorder,inorder,preleft2,preright2,inleft2,inright2); return root; } Btree * rebuild(vector<int> & preorder,vector<int> & inorder) { int end = preorder.size(); Btree * root = rebuild(preorder,inorder,0,end-1,0,end-1); return root; } //判斷是否是完全二叉樹 bool isCompleteBtree2(Btree * root) { queue<Btree*> queTemp; if (root) queTemp.push(root); while(queTemp.size()) { Btree * temp = queTemp.front(); queTemp.pop(); if (temp) { queTemp.push(temp->m_lchild); queTemp.push(temp->m_rchild); } else { while(queTemp.size()) { temp = queTemp.front(); queTemp.pop(); if (temp) { return false; } } } } return true; } //是否完全二叉樹 bool isCompleteBtree(Btree * root) { queue<Btree*> queueTemp; if(root) queueTemp.push(root); Btree * temp = queueTemp.front(); while(temp) { queueTemp.pop(); queueTemp.push(temp->m_lchild); queueTemp.push(temp->m_rchild); temp = queueTemp.front(); } while(queueTemp.size()) { temp = queueTemp.front(); if (temp) { return false; } queueTemp.pop(); } return true; } //destory Btree void destroyBtree(Btree * root) { if (root) { destroyBtree(root->m_lchild); destroyBtree(root->m_rchild); delete root; root = NULL; } }