1. 二叉樹的遍歷:先序(遞歸、非遞歸),中序(遞歸、非遞歸),後序(遞歸、非遞歸)。node
#include <iostream> #include <string> #include <stack> using namespace std; struct BiTree { int NodeData = 0; struct BiTree *pLeft = nullptr; struct BiTree *pRight = nullptr; }; //遍歷二叉樹: void show(struct BiTree *pRoot, int n) { if (pRoot == nullptr) { return; } else { show(pRoot->pLeft, n + 1); for (int i = 0; i < n; i++) cout << " "; cout << pRoot->NodeData << endl; show(pRoot->pRight, n + 1); } } //-------------------------------------------------------------- //遞歸中序遍歷: void RecMidTravel(struct BiTree *pRoot) { if (pRoot == nullptr) { return; } else { if (pRoot->pLeft != nullptr) { RecMidTravel(pRoot->pLeft); } cout << pRoot->NodeData << endl; if (pRoot->pRight != nullptr) { RecMidTravel(pRoot->pRight); } } } //中序非遞歸 void MidTravel(struct BiTree *pRoot) { if (pRoot == nullptr) { return; } else { struct BiTree *pcur = pRoot; stack<BiTree *> mystack; while (!mystack.empty() || pcur != nullptr) { while (pcur != nullptr) { mystack.push(pcur); pcur = pcur->pLeft; //左節點所有進棧 } if (!mystack.empty()) { pcur = mystack.top(); cout << pcur->NodeData << endl; mystack.pop(); //出棧 pcur = pcur->pRight; //右節點 } } } } //-------------------------------------------------------------- //遞歸先序遍歷: void RecPreTravel(struct BiTree *pRoot) { if (pRoot == nullptr) { return; } else { cout << pRoot->NodeData << endl; if (pRoot->pLeft != nullptr) { RecPreTravel(pRoot->pLeft); } if (pRoot->pRight != nullptr) { RecPreTravel(pRoot->pRight); } } } //先序非遞歸 void PreTravel(struct BiTree *pRoot) { if (pRoot == nullptr) { return; } else { struct BiTree *pcur = pRoot; stack<BiTree *> mystack; while (!mystack.empty() || pcur != nullptr) { while (pcur != nullptr) { cout << pcur->NodeData << endl; mystack.push(pcur); pcur = pcur->pLeft; //左節點所有進棧 } if (!mystack.empty()) { pcur = mystack.top(); mystack.pop(); //出棧 pcur = pcur->pRight; //右節點 } } } } //-------------------------------------------------------------- //遞歸後序遍歷: void RecPostTravel(struct BiTree *pRoot) { if (pRoot == nullptr) { return; } else { if (pRoot->pLeft != nullptr) { RecPostTravel(pRoot->pLeft); } if (pRoot->pRight != nullptr) { RecPostTravel(pRoot->pRight); } cout << pRoot->NodeData << endl; } } //後序非遞歸 struct nosame //標識節點是否反覆出現 { struct BiTree *pnode; bool issame; }; void PostTravel(struct BiTree *pRoot) { if (pRoot == nullptr) { return; } else { struct BiTree *pcur = pRoot; stack<nosame *> mystack; //避免重複出現 nosame *ptemp; while (!mystack.empty() || pcur != nullptr) { while (pcur != nullptr) { nosame *ptr = new nosame; ptr->issame = true; ptr->pnode = pcur;//節點 //cout << pcur->NodeData << endl; mystack.push(ptr); pcur = pcur->pLeft; //左節點所有進棧 } if (!mystack.empty()) { ptemp = mystack.top(); mystack.pop(); //出棧 if (ptemp->issame == true) //第一次出現 { ptemp->issame = false; mystack.push(ptemp); pcur = ptemp->pnode->pRight;//跳到右節點 } else { cout << ptemp->pnode->NodeData << endl;//打印數據 pcur = nullptr; } } } } } void main() { struct BiTree *pRoot; struct BiTree node1; struct BiTree node2; struct BiTree node3; struct BiTree node4; struct BiTree node5; struct BiTree node6; struct BiTree node7; struct BiTree node8; node1.NodeData = 1; node2.NodeData = 2; node3.NodeData = 3; node4.NodeData = 4; node5.NodeData = 5; node6.NodeData = 6; node7.NodeData = 7; node8.NodeData = 8; pRoot = &node1; node1.pLeft = &node2; node1.pRight = &node3; node2.pLeft = &node4; node2.pRight = &node5; node3.pLeft = &node6; node3.pRight = &node7; node4.pLeft = &node8; show(pRoot, 1); cout << "中序遞歸:" << endl; RecMidTravel(pRoot); //中序遞歸 cout << "中序非遞歸:" << endl; MidTravel(pRoot); //中序非遞歸 cout << "先序遞歸:" << endl; RecPreTravel(pRoot); cout << "先序非遞歸:" << endl; PreTravel(pRoot); //先序非遞歸 cout << "後序遞歸:" << endl; RecPostTravel(pRoot); cout << "後序非遞歸:" << endl; PostTravel(pRoot); //後序非遞歸 cin.get(); }
2. 獲取二叉樹節點個數:ios
//遞歸獲取二叉樹節點個數 int getNodeCount(BiTree *pRoot) { if (pRoot == nullptr) { return 0; } else { return getNodeCount(pRoot->pLeft) + getNodeCount(pRoot->pRight) + 1; } }
3. 判斷二叉樹是否爲徹底二叉樹:spa
//判斷二叉樹是否爲徹底二叉樹 bool isCompleteBiTree(BiTree *pRoot) { if (pRoot == nullptr) { return false; } else { queue<BiTree *> myq; myq.push(pRoot); bool mustHaveChild = false; //必須有子節點 bool result = true; //結果 while (!myq.empty()) { BiTree *node = myq.front();//頭結點 myq.pop(); //出隊 if (mustHaveChild) //必須有孩子 { if (node->pLeft != nullptr || node->pRight != nullptr) { result = false; break; } } else { if (node->pLeft != nullptr && node->pRight != nullptr) { myq.push(node->pLeft); myq.push(node->pRight); } else if (node->pLeft != nullptr && node->pRight == nullptr) { mustHaveChild = true; myq.push(node->pLeft); } else if (node->pLeft == nullptr && node->pRight != nullptr) { result = false; break; } else { mustHaveChild = true; } } } return result; } }
4. 求二叉樹兩個節點的最小公共祖先:3d
//求二叉樹兩個節點的最小公共祖先 bool findnode(BiTree *pRoot, BiTree *node) //判斷節點是否在某個節點下 { if (pRoot == nullptr || node == nullptr) { return false; } if (pRoot == node) { return true; } bool isfind = findnode(pRoot->pLeft, node); if (!isfind) { isfind = findnode(pRoot->pRight, node); } return isfind; } BiTree *getParent(BiTree *pRoot, BiTree *pChild1, BiTree *pChild2) { if (pRoot == pChild1 || pRoot == pChild2) { return pRoot; } if (findnode(pRoot->pLeft, pChild1)) { if (findnode(pRoot->pRight, pChild2)) { return pRoot; } else { return getParent(pRoot->pLeft, pChild1, pChild2); } } else { if (findnode(pRoot->pLeft, pChild2)) { return pRoot; } else { return getParent(pRoot->pRight, pChild1, pChild2); } } }
5. 二叉樹的翻轉:code
//二叉樹的翻轉 BiTree *revBiTree(BiTree *pRoot) { if (pRoot==nullptr) { return nullptr; } BiTree *leftp = revBiTree(pRoot->pLeft); BiTree *rightp = revBiTree(pRoot->pRight); pRoot->pLeft = rightp; pRoot->pRight = leftp; //交換 return pRoot; }
6. 求二叉樹第k層的節點個數:blog
//求二叉樹第K層的節點個數 int getLevelConut(BiTree *pRoot, int k) { if (pRoot == nullptr || k < 1) { return 0; } if (k == 1) { return 1; } else { int left = getLevelConut(pRoot->pLeft, k - 1); int right = getLevelConut(pRoot->pRight, k - 1); return (left + right); } }
7. 求二叉樹中節點的最大距離(相距最遠的兩個節點之間的距離):遞歸
//求二叉樹中節點的最大距離 struct res //用以遞歸間傳遞距離 { int maxDistance = 0; int maxDepth = 0; }; res getMaxDistance(BiTree *pRoot) { if (pRoot == nullptr) { res r1; return r1; } res leftr = getMaxDistance(pRoot->pLeft); res rightr = getMaxDistance(pRoot->pRight); res last; //最終結果 last.maxDepth = max(leftr.maxDepth + 1, rightr.maxDepth + 1);//求最大深度 last.maxDistance = max(max(leftr.maxDistance, rightr.maxDistance), leftr.maxDepth + rightr.maxDepth + 2);//求最大距離 return last; }
8. 判斷二叉樹是否爲平衡二叉樹:ci
//判斷二叉樹是否爲平衡二叉樹: bool isAVL(BiTree *pRoot, int & depth) //須要引用來傳遞數據 { if (pRoot == nullptr) { depth = 0; return true; } int leftdepth = 0; int rightdepth = 0; bool left = isAVL(pRoot->pLeft, leftdepth); bool right = isAVL(pRoot->pRight, rightdepth); if (left && right && abs(leftdepth - rightdepth) <= 1) { depth = 1 + (leftdepth > rightdepth ? leftdepth : rightdepth);//深度 return true; } else { return false; } }