数据结构--二叉树 Binary Tree
生活随笔
收集整理的這篇文章主要介紹了
数据结构--二叉树 Binary Tree
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
文章目錄
- 1.概念
- 2.存儲(chǔ)方式
- 2.1 鏈?zhǔn)酱鎯?chǔ)(二叉樹(shù)代碼大部分是鏈?zhǔn)綄?shí)現(xiàn)的)
- 2.2 順序存儲(chǔ)(基于數(shù)組)
- 3.二叉樹(shù)的遍歷
- 3.1 基于鏈表的二叉樹(shù)實(shí)現(xiàn)代碼
- 3.2 基于數(shù)組的二叉樹(shù)實(shí)現(xiàn)代碼
- 3.3 非遞歸法 二叉樹(shù)遍歷
1.概念
- 二叉樹(shù),每個(gè)節(jié)點(diǎn)最多有兩個(gè)“叉”,也就是兩個(gè)子節(jié)點(diǎn),分別是左子節(jié)點(diǎn)和右子節(jié)點(diǎn)。不過(guò),二叉樹(shù)并不要求每個(gè)節(jié)點(diǎn)都有兩個(gè)子節(jié)點(diǎn)
- 滿二又樹(shù),葉子節(jié)點(diǎn)全都在最底層,除了葉子節(jié)點(diǎn)之外,每個(gè)節(jié)點(diǎn)都有左右兩個(gè)子節(jié)點(diǎn)。
- 完全二叉樹(shù),葉子節(jié)點(diǎn)都在最底下兩層,最后一層的葉子節(jié)點(diǎn)都靠左排列,并且除了最后一層,其他層的節(jié)點(diǎn)個(gè)數(shù)都要達(dá)到最大。
2.存儲(chǔ)方式
2.1 鏈?zhǔn)酱鎯?chǔ)(二叉樹(shù)代碼大部分是鏈?zhǔn)綄?shí)現(xiàn)的)
2.2 順序存儲(chǔ)(基于數(shù)組)
- 把根節(jié)點(diǎn)存儲(chǔ)在下標(biāo) i = 1 的位置,那左子節(jié)點(diǎn)存儲(chǔ)在下標(biāo) 2 * i = 2 的位置,右子節(jié)點(diǎn)存儲(chǔ)在 2 * i + 1 = 3 的位置。
- 以此類推,B節(jié)點(diǎn)的左子節(jié)點(diǎn)存儲(chǔ)在 2 * i = 2 * 2 = 4 的位置,右子節(jié)點(diǎn)存儲(chǔ)在 2 * i + 1 = 2 * 2 + 1 = 5 的位置。
堆排序中的堆就是完全二叉樹(shù)。
3.二叉樹(shù)的遍歷
void preOrder(Node* root) {if(root==NULL)return;print root; //打印root節(jié)點(diǎn)preOrder(root->1eft);preOrder(root->right); } void inorder(Node* root) {if(root==NULL)return;inorder(root->1eft);print root; //打印root節(jié)點(diǎn)inorder(root->right); } void postorder(Node* root) {if(root==NULL)return;postorder(root->1eft);postorder(root->right);print root; //打印root節(jié)點(diǎn) } void levelorder(Node* root) //按層從左至右打印 {if(root==NULL)return;queue<node*> nodeQueuenodequeue.push(root);while(!nodequeue.empty()) //建立節(jié)點(diǎn)隊(duì)列,打印父節(jié)點(diǎn),入隊(duì)左右子節(jié)點(diǎn),出隊(duì)父節(jié)點(diǎn){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();} }每個(gè)節(jié)點(diǎn)最多會(huì)被訪問(wèn) 2 次, 所以遍歷操作的時(shí)間復(fù)雜度, 跟節(jié)點(diǎn)的個(gè)數(shù) n 成正比,二叉樹(shù)遍歷的時(shí)間復(fù)雜度是 O(n)
3.1 基于鏈表的二叉樹(shù)實(shí)現(xiàn)代碼
/*** @description: 二叉樹(shù),鏈表實(shí)現(xiàn)* @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; //返回創(chuàng)建好的left節(jié)點(diǎn)l,跟父接上node<T>* r = insert(nodep->right, lv-1, toplv, 2*data+1);if(r)nodep->right = r; //返回創(chuàng)建好的right節(jié)點(diǎn)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()) //建立節(jié)點(diǎn)隊(duì)列,打印父節(jié)點(diǎn),入隊(duì)左右子節(jié)點(diǎn),出隊(duì)父節(jié)點(diǎn){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;}//-----------------求二叉樹(shù)高度-----------------------int get_height(node<T>* nodep) //遞歸法, 求左右子樹(shù)高度,較大的+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) //按層計(jì)算高度{if (nodep == NULL)return 0;queue<node<T>*> nodequeue;node<T>* p = NULL;nodequeue.push(nodep);int height = 0;while(!nodequeue.empty()) //建立節(jié)點(diǎn)隊(duì)列,入隊(duì)左右子節(jié)點(diǎn),出隊(duì)父節(jié)點(diǎn){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) //用棧實(shí)現(xiàn)前序(或后序)遍歷,最大棧長(zhǎng)度即為樹(shù)的高度{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;//找到最底端左節(jié)點(diǎn)}else{nodep = nodestack.top();//最底端左節(jié)點(diǎn)的父節(jié)點(diǎn)nodepif(nodep->right != NULL && nodep->right != temp) //右邊有節(jié)點(diǎn),且沒(méi)有進(jìn)過(guò)棧nodep = nodep->right; //進(jìn)入右節(jié)點(diǎn),跳到上個(gè)if查其子樹(shù)else //沒(méi)有子節(jié)點(diǎn),或者子節(jié)點(diǎn)進(jìn)過(guò)棧{if(nodestack.size() > height)height = nodestack.size(); //更新最大高度temp = nodep; //記錄彈棧的節(jié)點(diǎn)到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 基于數(shù)組的二叉樹(shù)實(shí)現(xiàn)代碼
/*** @description: 二叉樹(shù),數(shù)組實(shí)現(xiàn)* @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 非遞歸法 二叉樹(shù)遍歷
- 前序(入棧root,訪問(wèn)stack.top(), 出棧,依次入棧右節(jié)點(diǎn),左節(jié)點(diǎn))
- 中序(入棧右、根、(左的右、左的根、…),左右節(jié)點(diǎn)為空,到達(dá)葉子節(jié)點(diǎn),打印葉子節(jié)點(diǎn),)
- 后序
完整代碼
總結(jié)
以上是生活随笔為你收集整理的数据结构--二叉树 Binary Tree的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 回溯算法(Backtracking Al
- 下一篇: LeetCode 59. 螺旋矩阵 II