数据结构--二叉树 Binary Tree
生活随笔
收集整理的這篇文章主要介紹了
数据结构--二叉树 Binary Tree
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1.概念
- 2.存儲方式
- 2.1 鏈式存儲(二叉樹代碼大部分是鏈式實現的)
- 2.2 順序存儲(基于數組)
- 3.二叉樹的遍歷
- 3.1 基于鏈表的二叉樹實現代碼
- 3.2 基于數組的二叉樹實現代碼
- 3.3 非遞歸法 二叉樹遍歷
1.概念
- 二叉樹,每個節點最多有兩個“叉”,也就是兩個子節點,分別是左子節點和右子節點。不過,二叉樹并不要求每個節點都有兩個子節點
- 滿二又樹,葉子節點全都在最底層,除了葉子節點之外,每個節點都有左右兩個子節點。
- 完全二叉樹,葉子節點都在最底下兩層,最后一層的葉子節點都靠左排列,并且除了最后一層,其他層的節點個數都要達到最大。
2.存儲方式
2.1 鏈式存儲(二叉樹代碼大部分是鏈式實現的)
2.2 順序存儲(基于數組)
- 把根節點存儲在下標 i = 1 的位置,那左子節點存儲在下標 2 * i = 2 的位置,右子節點存儲在 2 * i + 1 = 3 的位置。
- 以此類推,B節點的左子節點存儲在 2 * i = 2 * 2 = 4 的位置,右子節點存儲在 2 * i + 1 = 2 * 2 + 1 = 5 的位置。
堆排序中的堆就是完全二叉樹。
3.二叉樹的遍歷
void preOrder(Node* root) {if(root==NULL)return;print root; //打印root節點preOrder(root->1eft);preOrder(root->right); } void inorder(Node* root) {if(root==NULL)return;inorder(root->1eft);print root; //打印root節點inorder(root->right); } void postorder(Node* root) {if(root==NULL)return;postorder(root->1eft);postorder(root->right);print root; //打印root節點 } void levelorder(Node* root) //按層從左至右打印 {if(root==NULL)return;queue<node*> nodeQueuenodequeue.push(root);while(!nodequeue.empty()) //建立節點隊列,打印父節點,入隊左右子節點,出隊父節點{node* p = nodeQueue.front();cout << p->data << " ";if(p->left != NULL)nodeQueue.push(p->left);if(p->right != NULL)nodeQueue.push(p->right);nodeQueue.pop();} }每個節點最多會被訪問 2 次, 所以遍歷操作的時間復雜度, 跟節點的個數 n 成正比,二叉樹遍歷的時間復雜度是 O(n)
3.1 基于鏈表的二叉樹實現代碼
/*** @description: 二叉樹,鏈表實現* @author: michael ming* @date: 2019/5/11 18:03* @modified by: */ #include <iostream> #include <queue> #include <stack> using namespace std; template <class T> struct node {T data;node<T> *left, *right;node<T>():left(NULL), right(NULL){} }; template <class T> class binary_tree { private:int nodelen;node<T> *root; public:binary_tree():nodelen(0), root(NULL){}node<T>* getRoot()const{return root;}node<T>* insert(node<T> * nodep, size_t lv, size_t toplv, int data = 1){if(lv == 0)return NULL;else if(nodep == NULL && lv == toplv){root = new node<T>();nodep = root;}else{nodep = new node<T>();}nodep->data = data;nodelen++;node<T>* l = insert(nodep->left, lv-1, toplv, 2*data);if(l)nodep->left = l; //返回創建好的left節點l,跟父接上node<T>* r = insert(nodep->right, lv-1, toplv, 2*data+1);if(r)nodep->right = r; //返回創建好的right節點r,跟父接上return nodep;}void preOrderPrint(node<T> * nodep){if (nodep == NULL)return;cout << nodep->data << " ";preOrderPrint(nodep->left);preOrderPrint(nodep->right);}void inOrderPrint(node<T> * nodep){if (nodep == NULL)return;inOrderPrint(nodep->left);cout << nodep->data << " ";inOrderPrint(nodep->right);}void postOrderPrint(node<T> * nodep){if (nodep == NULL)return;postOrderPrint(nodep->left);postOrderPrint(nodep->right);cout << nodep->data << " ";}void levelOrderPrint(node<T> * nodep) //按層打印{if (nodep == NULL)return;queue<node<T>*> nodequeue;nodequeue.push(nodep);while(!nodequeue.empty()) //建立節點隊列,打印父節點,入隊左右子節點,出隊父節點{node<T>* p = nodequeue.front();cout << p->data << " ";if(p->left != NULL)nodequeue.push(p->left);if(p->right != NULL)nodequeue.push(p->right);nodequeue.pop();}}void destory_tree(node<T> * nodep){if (nodep == NULL)return;destory_tree(nodep->left);destory_tree(nodep->right);delete nodep;}//-----------------求二叉樹高度-----------------------int get_height(node<T>* nodep) //遞歸法, 求左右子樹高度,較大的+1{if(nodep == NULL)return 0;int leftheight = get_height(nodep->left);int rightheight = get_height(nodep->right);return max(leftheight, rightheight) + 1;}int level_get_height(node<T>* nodep) //按層計算高度{if (nodep == NULL)return 0;queue<node<T>*> nodequeue;node<T>* p = NULL;nodequeue.push(nodep);int height = 0;while(!nodequeue.empty()) //建立節點隊列,入隊左右子節點,出隊父節點{height++;int n = nodequeue.size();for(int i = 0; i < n; ++i){p = nodequeue.front();if(p->left != NULL)nodequeue.push(p->left);if(p->right != NULL)nodequeue.push(p->right);nodequeue.pop();}}return height;}int stack_get_height(node<T>* nodep) //用棧實現前序(或后序)遍歷,最大棧長度即為樹的高度{if (nodep == NULL)return 0;stack<node<T>*> nodestack;node<T> *temp = NULL;int height = 0;while(nodep != NULL || !nodestack.empty()){if(nodep != NULL){nodestack.push(nodep);nodep = nodep->left;//找到最底端左節點}else{nodep = nodestack.top();//最底端左節點的父節點nodepif(nodep->right != NULL && nodep->right != temp) //右邊有節點,且沒有進過棧nodep = nodep->right; //進入右節點,跳到上個if查其子樹else //沒有子節點,或者子節點進過棧{if(nodestack.size() > height)height = nodestack.size(); //更新最大高度temp = nodep; //記錄彈棧的節點到tempnodestack.pop();nodep = NULL;}}}return height;} };int main() {binary_tree<int> btree;btree.insert(btree.getRoot(), 3, 3);btree.preOrderPrint(btree.getRoot());cout << endl << endl;btree.inOrderPrint(btree.getRoot());cout << endl << endl;btree.postOrderPrint(btree.getRoot());cout << endl << endl;btree.levelOrderPrint(btree.getRoot());cout << endl;cout << "height of tree: " << btree.get_height(btree.getRoot()) << endl;cout << "level height of tree: " << btree.level_get_height(btree.getRoot()) << endl;cout << "stack height of tree: " << btree.stack_get_height(btree.getRoot()) << endl;btree.destory_tree(btree.getRoot());return 0; }
3.2 基于數組的二叉樹實現代碼
/*** @description: 二叉樹,數組實現* @author: michael ming* @date: 2019/5/11 11:44* @modified by: */ #include <iostream> using namespace std; template <class T> struct node {T data;node<T>(){} }; template <class T> class binary_tree { private:int size;size_t tree_arrlen;node<T>* tree; public:binary_tree(int len = 20):size(len),tree_arrlen(0){tree = new node<T> [size];}~binary_tree(){delete [] tree;}void insert(T &data){if(tree_arrlen < size)tree[++tree_arrlen].data = data;}void preOrderPrint(size_t index = 1){if(tree_arrlen < 1 || index > tree_arrlen)return;cout << tree[index].data << " ";preOrderPrint(index*2);preOrderPrint(index*2+1);}void inOrderPrint(size_t index = 1){if(tree_arrlen < 1 || index > tree_arrlen)return;inOrderPrint(index*2);cout << tree[index].data << " ";inOrderPrint(index*2+1);}void postOrderPrint(size_t index = 1){if(tree_arrlen < 1 || index > tree_arrlen)return;postOrderPrint(index*2);postOrderPrint(index*2+1);cout << tree[index].data << " ";} };int main() {binary_tree<int> btree;for(int i = 1; i < 8; ++i)btree.insert(i);btree.preOrderPrint();cout << endl;btree.inOrderPrint();cout << endl;btree.postOrderPrint();return 0; }3.3 非遞歸法 二叉樹遍歷
- 前序(入棧root,訪問stack.top(), 出棧,依次入棧右節點,左節點)
- 中序(入棧右、根、(左的右、左的根、…),左右節點為空,到達葉子節點,打印葉子節點,)
- 后序
完整代碼
總結
以上是生活随笔為你收集整理的数据结构--二叉树 Binary Tree的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 回溯算法(Backtracking Al
- 下一篇: php表白页面,2020情人节表白页面(