二叉树是一种非线性结构,用途非常广泛。二叉树它的每一个结点的度都不大于2,所以一般用二叉链表来实现二叉树。
二叉链表:
二叉树可以分为根结点和左子树,右子树。左子树和右子树依旧可以这样划分。所以二叉树是典型的递归结构,所以用递归来实现二叉树的逻辑是非常简单的,只要不断的对二叉树进行划分即可。递归创建二叉树的时候选择先序创建时最简单的。
#include<iostream>
using namespace std;
#include<assert.h>
#include<queue>
#include<stack>
template<typename T>
struct BinaryTreeNode
{
T _data;
BinaryTreeNode<T>* _left;
BinaryTreeNode<T>* _right;
BinaryTreeNode(const T& x)
:_data(x)
,_left(NULL)
,_right(NULL)
{}
};
template<typename T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree()
:_root(NULL)
{}
BinaryTree(T* a,size_t n,const T& invalid)
{
assert(a);
size_t index=0;
_root=_CreateBinaryTree(a,n,index,invalid);
}
BinaryTree(const BinaryTree<T>& t)
{
_root=_Copy(t._root);
}
BinaryTree<T>& operator=(const BinaryTree<T>& t)
{
if(this!=&t)
{
Node* root=_Copy(t._root);
_Destory(_root);
_root=root;
}
return *this;
}
~BinaryTree()
{
_Destory(_root);
}
void Prev()
{
_Prev(_root);
cout<<endl;
}
void In()
{
_In(_root);
cout<<endl;
}
void Post()
{
_Post(_root);
cout<<endl;
}
void Level()
{
queue<Node*> q;
Node* cur=_root;
q.push(cur);
while(!q.empty())
{
Node* tmp=q.front();
cout<<tmp->_data<<" ";
if(tmp->_left!=NULL)
q.push(tmp->_left);
if(tmp->_right!=NULL)
q.push(tmp->_right);
q.pop();
}
cout<<endl;
}
void PrevR()
{
stack<Node*> s;
Node* cur=_root;
while(cur||!s.empty())
{
while(cur)
{
cout<<cur->_data<<" ";
s.push(cur);
cur=cur->_left;
}
Node* top=s.top();
s.pop();
cur=top->_right;
}
cout<<endl;
}
void InR()
{
stack<Node*> s;
Node* cur=_root;
while(cur||!s.empty())
{
while(cur)
{
s.push(cur);
cur=cur->_left;
}
Node* top=s.top();
cout<<top->_data<<" ";
s.pop();
cur=top->_right;
}
cout<<endl;
}
void
size_t Size()
{
return _Size(_root);
}
size_t Depth()
{
return _Depth(_root);
}
size_t Leaf()
{
return _Leaf(_root);
}
Node* Find(const T& x)
{
return _Find(_root,x);
}
protected:
Node* _CreateBinaryTree(const T* a,size_t n,size_t& index,const T& invalid)
{
Node* root=NULL;
if(index<n&&a[index]!=invalid)
{
root=new Node(a[index]);
root->_left=_CreateBinaryTree(a,n,++index,invalid);
root->_right=_CreateBinaryTree(a,n,++index,invalid);
}
return root;
/*
Node* cur=NULL;
Node* root=NULL;
stack<Node*> s;
while(index<n)
{
while(index<n&&a[index]!=invalid)
{
if(index==0)
{
root=new Node(a[index]);
index++;
cur=root;
}
else
{
cur->_left=new Node(a[index]);
index++;
cur=cur->_left;
}
s.push(cur);
}
index++;
Node* top=s.top();
s.pop();
if(index<n&&a[index]!=invalid)
{
cur=top;
cur->_right=new Node(a[index]);
index++;
cur=cur->_right;
s.push(cur);
}
}
return root;*/
}
Node* _Copy(Node* root)
{
if(root!=NULL)
{
Node* newNode=new Node(root->_data);
newNode->_left=_Copy(root->_left);
newNode->_right=_Copy(root->_right);
}
return newNode;
}
void _Destory(Node* root)
{
if(root!=NULL)
{
_Destory(root->_left);
_Destory(root->_right);
delete root;
}
}
void _Prev(Node* root)
{
if(root!=NULL)
{
cout<<root->_data<<" ";
_Prev(root->_left);
_Prev(root->_right);
}
}
void _In(Node* root)
{
if(root!=NULL)
{
_In(root->_left);
cout<<root->_data<<" ";
_In(root->_right);
}
}
void _Post(Node* root)
{
if(root!=NULL)
{
_Post(root->_left);
_Post(root->_right);
cout<<root->_data<<" ";
}
}
size_t _Size(Node* root)
{
if(root==NULL)
return 0;
return 1+_Size(root->_left)+_Size(root->_right);
}
size_t _Size1(Node* root)
{
int count=0;
if(root==NULL)
return 0;
count++;
_Size(root->_left);
_Size(root->_right);
return count;
}
size_t _Leaf(Node* root)
{
if(root==NULL)
return 0;
if(root->_left==NULL&&root->_right==NULL)
return 1;
return _Leaf(root->_left)+_Leaf(root->_right);
}
size_t _Depth(Node* root)
{
if(root==NULL)
return 0;
return _Depth(root->_left)>_Depth(root->_right)?_Depth(root->_left)+1:_Depth(root->_right)+1;
}
Node* _Find(Node* root,const T& x)
{
if(root==NULL)
return NULL;
if(root->_data==x)
return root;
_Find(root->_left,x);
_Find(root->_right,x);
}
protected:
Node* _root;
};
int main()
{
int arr[10]={1,2,3,'#','#',4,'#','#',5,6};
BinaryTree<int> t1(arr,10,'#');
t1.Prev();
t1.PrevR();
t1.In();
t1.InR();
t1.Post();
t1.Level();
cout<<"Size:"<<t1.Size()<<endl;
cout<<"Leaf:"<<t1.Leaf()<<endl;
cout<<"Depth:"<<t1.Depth()<<endl;
system("pause");
return 0;
}