【資料結構】二叉樹!!!
概念:
一顆二叉樹是結點的一個有限集合,該集合為空或者是由一個根節點和一個左子樹和一個右子樹構成的組合。
特點:
每個結點最多有兩個子樹,每個子樹的順序不能變,份左子樹和右子樹。
分類:
滿二叉樹:在一棵樹裡面每個分支結點都存在左子樹和右子樹,並且所有的葉子節點都在同一層。
完全二叉樹:一棵具有N個結點的二叉樹的結構和滿二叉樹的前N個結點相
二叉樹的性質
若二叉樹根結點的層數為1,那麼這個非空二叉樹的第i層最多有2^(i-1)個結點。
若根節點二叉樹的深度為1,那麼深度為K的二叉樹的最大結點數是2^K-1;
對於任何一棵二叉樹,如果葉節點個數為N0,度為2的非葉節點的個數為N1,那麼N0 = N1+1;
二叉樹的基本操作:
二叉樹的遍歷
前序:
- 先訪問根節點—–>左子樹 —–>右子樹
結果:A B D E C F
中序:
- 左子樹—–>訪問根結點—– >右子樹
結果:D B E A F C
後序:
- 左子樹—–>根節點—–>訪問右子樹
結果:D E B F C A
層序:
- 每一層順序遍歷二叉樹
結果:A B C D E F
【二叉樹的基本操作程式碼】
#include<stack>
#include<iostream>
using namespace std;
template<class T>
struct TreeNode
{
TreeNode()
:leftTree(NULL)
,rightTree(NULL)
{}
TreeNode(T& d)
:leftTree(NULL)
,rightTree(NULL)
,data(d)
{}
TreeNode(const TreeNode& t)
:leftTree(t.leftTree)
,rightTree(t.rightTree)
,data(t.data)
{}
TreeNode<T>* leftTree;
TreeNode<T>* rightTree;
T data;
};
template<class T>
class BinaryTree
{
typedef TreeNode<T> Node;
public:
BinaryTree(T* arr,size_t N,T& invalid) //construct function
:_root(NULL)
{
if(arr)
{
size_t index = 0;
_root = GreatTreeNode(_root,arr,N,index,invalid);
}
}
BinaryTree(BinaryTree<T>& t) //copy construction
{
_root = _CopyTree(t._root);
}
Node* _CopyTree(Node *root2) //copy tree
{
if(NULL == root2)
return NULL;
Node* root1 = new Node(root2->data);
root1->leftTree = _CopyTree(root2->leftTree);
root1->rightTree = _CopyTree(root2->rightTree);
return root1;
}
void PrePrint() //print by front
{
_PrePrint(_root);
}
void _PrePrint(Node* root)
{
if(NULL == root)
return ;
cout<<root->data<<" ";
_PrePrint(root->leftTree);
_PrePrint(root->rightTree);
//cout<<endl;
}
void PreOrder()
{
if(NULL == _root)
return ;
stack<Node*> s;
s.push(_root);
Node* tmp = _root;
while(!s.empty())
{
tmp = s.top();
s.pop();
while(tmp)
{
cout<<tmp->data<<" ";
if(tmp->rightTree)
s.push(tmp->rightTree);
tmp = tmp->leftTree;
}
}
}
void Inorder()
{
if(NULL == _root)
return ;
stack<Node*> s;
Node *tmp = _root;
while(!s.empty())
{
while(tmp)
{
s.push(tmp);
tmp = tmp->leftTree;
}
tmp = s.top();
cout<<tmp->data<<" ";
s.pop();
tmp = tmp->rightTree;
}
}
void BackOrder()
{
if(NULL == _root)
return ;
stack<Node*> s;
Node* tmp = _root;
Node* flag = NULL;
s.push(_root);
while(!s.empty()||tmp)
{
while(tmp)
{
if(tmp->leftTree)
s.push(tmp->leftTree);
tmp = tmp->leftTree;
}
tmp = s.top();
if(NULL == tmp->rightTree || flag == tmp->rightTree)
{
cout<<tmp->data<<" ";
s.pop();
flag = tmp;
tmp = NULL;
}
else
tmp = tmp->rightTree;
}
}
/*
void PreOrder_NoR() //非遞迴前序遍歷
{
if(NULL == _root)
return ;
stack<Node*> s;
s.push(_root);
while(!s.empty())
{
Node* tmp = s.top();
s.pop();
while(tmp)
{
cout<<tmp->data<<" ";
if(tmp->rightTree)
s.push(tmp->rightTree);
tmp = tmp->leftTree;
}
}
}
void InOrder() //非遞迴中序遍歷
{
if(NULL == _root)
return ;
stack<Node*> s;
Node*tmp = _root;
while(!s.empty()||tmp)
{
while(tmp)
{
s.push(tmp);
tmp = tmp->leftTree;
}
tmp = s.top();
s.pop();
cout<<tmp->data<<" ";
tmp = tmp->rightTree;
}
}
void BackOrder() //非遞迴後序遍歷
{
if(NULL == _root)
return ;
stack<Node*> s;
Node* tmp = _root;
Node* flag = NULL;
while(!s.empty()||tmp)
{
while(tmp)
{
s.push(tmp);
tmp = tmp->leftTree;
}
tmp = s.top();
if(NULL == tmp->rightTree || flag == tmp->rightTree)
{
cout<<tmp->data<<" ";
flag = tmp;
s.pop();
tmp = NULL;
}
else
tmp = tmp->rightTree;
}
}
*/
void MidPrint() //Print by mid
{
_MidPrint(_root);
}
void _MidPrint(Node *root)
{
if(NULL == root)
return ;
_MidPrint(root->leftTree);
cout<<root->data<<" ";
_MidPrint(root->rightTree);
}
void BackPrint() //Print by back
{
_BackPrint(_root);
}
void _BackPrint(Node * root)
{
if(NULL == root)
return ;
_BackPrint(root->leftTree);
_BackPrint(root->rightTree);
cout<<root->data<<" ";
}
void FloorPrint() //
{
if(_root == NULL)
return ;
stack<Node*> s;
s.push(_root);
while(!s.empty())
{
Node* front = s.top();
s.pop();
cout<<front->data<<" ";
if(front->leftTree)
s.push(front->leftTree);
if(front->rightTree)
s.push(front->rightTree);
}
}
size_t DepthOfTree() //Get tree depth
{
return _DepthOfTree(_root);
}
size_t _DepthOfTree(Node* root)
{
if(NULL == root)
return 0;
size_t leftdepth = _DepthOfTree(root->leftTree);
size_t rightdepth = _DepthOfTree(root->rightTree);
return leftdepth > rightdepth ? (leftdepth+1):(rightdepth + 1);
}
size_t leafOfKfloorTree(size_t k) //Find K floor Node
{
size_t leafnum = 0;
return _leafOfKfloorTree(_root,k,leafnum);
}
size_t _leafOfKfloorTree(Node *root,size_t& k,size_t leafnum)
{
if(NULL == root)
return 0;
static size_t num = 0;
if(leafnum == k)
{
++num;
return num;
}
_leafOfKfloorTree(root->leftTree,k,leafnum+1);
_leafOfKfloorTree(root->rightTree,k,leafnum+1);
return num;
}
size_t GetLeafNum()
{
return _GetLeafNum(_root);
}
size_t _GetLeafNum(Node* root)
{
if(NULL == root)
return 0;
if(NULL == root->leftTree&&NULL == root->rightTree)
return 1;
size_t leftNum = _GetLeafNum(root->leftTree);
size_t rightNum = _GetLeafNum(root->rightTree);
return leftNum + rightNum;
}
size_t leafNum() //Get Tree leaf count
{
return _leafNum(_root);
}
size_t _leafNum(Node *root)
{
if(NULL == root)
return 0;
return _leafNum(root->leftTree) + _leafNum(root->rightTree) + 1;
}
Node* Find(T& d) //Find object data
{
return _Find(_root,d);
}
Node * _Find(Node *root,T& d)
{
if(NULL == root)
return NULL;
if(root->data == d)
return root;
Node* tmp = _Find(root->leftTree,d);
if(tmp)
return tmp;
return _Find(root->rightTree,d);
}
Node* leftchild(Node* pos) //Get left child Node
{
return _leftchild(_root,pos);
}
Node* _leftchild(Node* root,Node* pos)
{
if(NULL == root||pos == NULL)
return NULL;
return pos->leftchild;
}
Node* rightchild(Node* pos) //Get right child node
{
return _rightchild(_root,pos);
}
Node* _rightchild(Node* root,Node* pos)
{
if(NULL == root||NULL == pos)
return NULL;
return pos->rightTree;
}
Node* ParentNode(Node* pos) //Get parent Node
{
return _ParentNode(_root,pos);
}
Node* _ParentNode(Node* root,Node* pos)
{
if(NULL == root||NULL == pos)
return NULL;
if(root->leftTree == pos||root->rightTree == pos)
return root;
Node* tmp = _ParentNode(root->leftTree,pos);
if(tmp)
return tmp;
return _ParentNode(root->rightTree,pos);
}
size_t Size() //Get Tree node count
{
return _Size(_root);
}
size_t _Size(Node* root)
{
if(NULL == root)
return 0;
return _Size(root->leftTree) + _Size(root->rightTree) + 1;
}
BinaryTree& operator=(const BinaryTree& b)
{
if(this != &b)
{
DestoryTree(_root);
_root = _CopyTree(b._root);
}
return *this;
}
~BinaryTree()
{
DestoryTree(_root);
}
private:
void DestoryTree(Node *del)
{
if(NULL == del)
return ;
DestoryTree(del->leftTree);
DestoryTree(del->rightTree);
delete del;
del = NULL;
}
Node* GreatTreeNode(Node* root,T* arr,size_t N,size_t& index,T& invalid)
{
root = NULL;
if(index < N && arr[index] != invalid)
{
root = new Node(arr[index]);
root->leftTree = GreatTreeNode(root,arr,N,++index,invalid);
root->rightTree = GreatTreeNode(root,arr,N,++index,invalid);
}
return root;
}
Node *_root;
};
相關文章
- 資料結構(樹):二叉樹資料結構二叉樹
- 資料結構-二叉樹資料結構二叉樹
- 資料結構 - 二叉樹資料結構二叉樹
- 資料結構-平衡二叉樹資料結構二叉樹
- 資料結構之「二叉樹」資料結構二叉樹
- 資料結構——平衡二叉樹資料結構二叉樹
- 資料結構中的樹(二叉樹、二叉搜尋樹、AVL樹)資料結構二叉樹
- 資料結構——二叉樹進階資料結構二叉樹
- 資料結構-二叉搜尋樹資料結構
- 資料結構 二叉樹遍歷資料結構二叉樹
- 【資料結構】二叉搜尋樹!!!資料結構
- 資料結構分析之二叉樹資料結構二叉樹
- 【資料結構】回顧二叉樹資料結構二叉樹
- 【資料結構】二叉樹(c++)資料結構二叉樹C++
- 資料結構二叉樹學習資料結構二叉樹
- 資料結構-二叉樹、堆、圖資料結構二叉樹
- 資料結構——樹與二叉樹的遍歷資料結構二叉樹
- 重學資料結構之樹和二叉樹資料結構二叉樹
- 重學資料結構(六、樹和二叉樹)資料結構二叉樹
- [資料結構] 樹、二叉樹、森林的轉換資料結構二叉樹
- 資料結構之「二叉搜尋樹」資料結構
- 資料結構☞二叉搜尋樹BST資料結構
- 資料結構之二叉樹的建立資料結構二叉樹
- 資料結構之遍歷二叉樹資料結構二叉樹
- 【資料結構】建立二叉樹的方法資料結構二叉樹
- 資料結構之樹結構概述(含滿二叉樹、完全二叉樹、平衡二叉樹、二叉搜尋樹、紅黑樹、B-樹、B+樹、B*樹)資料結構二叉樹
- 資料結構 其五 樹與二叉樹學習總結資料結構二叉樹
- 【資料結構導論之樹和二叉樹總結篇】資料結構二叉樹
- 資料結構的故事之二叉樹, 字首樹, N叉樹資料結構二叉樹
- 【資料結構與演算法】二叉樹資料結構演算法二叉樹
- 常用資料結構之線索二叉樹資料結構二叉樹
- 資料結構和演算法:二叉樹資料結構演算法二叉樹
- 資料結構之線索化二叉樹資料結構二叉樹
- 【資料結構】二叉樹的線索化!!資料結構二叉樹
- 資料結構之二叉樹遞迴操作資料結構二叉樹遞迴
- C#資料結構-二叉樹-順序儲存結構C#資料結構二叉樹
- 資料結構-二叉樹的儲存結構與遍歷資料結構二叉樹
- 資料結構:樹和二叉樹定義和術語資料結構二叉樹