在介绍二叉树之前大家一定要对树有一定的了解,二叉树是一种特殊的树结构,二叉树每个节点最多有两个孩子节点,分别为左孩子和右孩子。
*满二叉树:高度为N的满二叉树有2^n-1个节点的二叉树。
*完全二叉树:若设二叉树的深度为h,除第h层外,其他各层(1~h-1)的节点数都达到最大个数,第h层所有的节点都连续集中在最左边,这就是完全二叉树。
*数组存储表示
当在数据处理过程中,二叉树的大小和形态不发生剧烈的动态变化时,可以采用数组的方式来表示二叉树的抽象数据结构类型。
用数组方式存储二叉树结构,就是用一组连续的存储单元存储二叉树的数据元素,为了反映节点在二叉树中的存储位置及相互关系,必须适当安排节点的存储
序。下面用数组来存储一个完全二树和一般二叉树来。
*链表存储表示
根据二叉树定义,可以设计出二叉树节点的构造。二叉树的每个节点至少应该包括三个域:数据data、左子女节点指针和右子女节点指针rightChild,如图(a)所示。这种链
表结构称为二叉树链表,使用这种结构可以很方便地根据节点leftChild指针和rightChild指针找到他的左子女和右子女
*遍历二叉树的方法:
(1)前序遍历(先根遍历):根节点->左子树->右子树;【123456】
(2)中序遍历:左子树->根节点->右子树;【324165】
(3)后序遍历:左子树->右子树->根节点;【342651】
(4)层序遍历:一层层节点依次遍历。【125346】
当然遍历二叉树的方法不知这些,这只是比较简单的几种。
*代码实现二叉树
#include<iostream>
#include<stack>
#include<queue>
#include<assert.h>
using namespace std;
//节点定义
template<class T>
struct BinaryTreeNode
{
T _data;//数据
BinaryTreeNode<T>* _left;//左孩子
BinaryTreeNode<T>* _right;//右孩子
BinaryTreeNode(const T& x)
:_data(x)
,_left(NULL)
,_right(NULL)
{}
};
//定义二叉树
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree()
:root(NULL)
{}
BinaryTree(T* a,size_t n,const T&invalid)
{
size_t index=0;
_root=CreateTree(a,n,invalid,index);
}
Node* _copy(Node* root)
{
if(root==NULL)
return NULL;
Node* newRoot=new Node(root->_data);
newRoot->_left=_copy(root->_left);
newRoot->_right=_copy(root->_right);
return newRoot;
}
BinaryTree(const BinaryTree<T>& t)
{
_root=_copy(t._root);
}
BinaryTree<T>& operator=(BinaryTree<T> t)
{
swap(_root,t._root);
return *this;
}
~BinaryTree()
{
Destory(_root);
}
void Destory(Node* root)
{
if(root==NULL)
return;
Destory(root->_left);
Destory(root->_right);
delete root;
}
void PrevOrder()
{
_PrevOrder(_root);
cout<<endl;
}
void InOrder()
{
_InOrder(_root);
cout<<endl;
}
void PrevOrderNonR()
{
stack<Node*> s;
Node* cur=_root;
while(cur||!s.empty())
{
while(cur)
{
cout<<cur->_data<<" ";
s.push(cur);
cur=cur->_left;
}
//top从栈取出来表示这个节点的左子树访问过了
//剩余右子树还没有访问,循环子问题访问右数
Node* top=s.top();
s.pop();
//子问题的方式访问右数
cur=top->_right;
}
cout<<endl;
}
void InOrderNonR()//非递归实现先序遍历
{
Node* cur=_root;
stack<Node*> s;
while(cur||!s.empty())
{
while(cur)
{
s.push(cur);
cur=cur->_left;
}
Node* top=s.top;
s.pop();
cout<<top->_data<<" ";
//子问题
cur=top->_right;
}
}
void PostOrderNonR()//非递归实现后序遍历
{
Node* cur=_root;
stack<Node*> s;
Node* prev=NULL;
while(cur||!s.empty())
{
while(cur)
{
s.push(cur);
cur=cur->_left;
}
Node* front=s.top();
if(front->_right==NULL||front->_right==prev)
{
cout<<front->_data<<" ";
prev=front;
s.pop();
}
else
{
cur=front->_right;
}
}
cout<<endl;
}
void LevelOrder()//层序遍历
{
queue<Node*> q;
if(_root)
{
q.push(_root);
}
while(!q.empty())
{
Node* front=q.front();
cout<<front->_data<<" ";
if(front->_left)
q.push(front->_left);
if(front->_right)
q.push(front->_right);
q.pop();
}
cout<<endl;
}
size_t Size()//求树的大小
{
return _Size(_root);
}
size_t LeafSize()//求叶子节点的个数
{
return _LeafSize(_root);
}
size_t GetkLeavel(size_t k)//求第K层叶子结点的个数
{
assert(k>0);
return _GetkLeavel(_root,k);
}
Node* Find(const T& x)//查找某个节点
{
return _Find(_root,x);
}
size_t Depth()//求1树的深度
{
return _Depth(_root);
}
protected://真正实现的部分
void _PrevOrder(Node* root)
{
if(root==NULL)
return;
cout<<root->_data;
_PrevOrder(root->_left);
_PrevOrder(root->_right);
}
void _InOrder(Node* root)
{
if(root==NULL)
return;
_InOrder(root->_left);
cout<<root->_data<<" ";
_InOrder(root->_right);
}
Node* CreateTree(T* a,size_t n,const T& invalid,size_t& index)
{
Node* root=NULL;
if(index<n&&a[index]!=invalid)
{
root=new Node(a[index]);
root->_left=CreateTree(a,n,invalid,++index);
root->_right=CreateTree(a,n,invalid,++index);
}
return root;
}
size_t _Size(Node* root)
{
if(root==NULL)
{
return 0;
}
return _Size(root->_left)+_Size(root->_right)+1;
}
size_t _LeafSize(Node* root)
{
if(root==NULL)
{
return 0;
}
if(root->_left==NULL||root->_right==NULL)
{
return 1;
}
return _LeafSize(root->_left)+_LeafSize(root->_right);
}
size_t _GetkLeavel(Node* root,size_t k)
{
if(root==NULL)
{
return 0;
}
if(k==1)
{
return 1;
}
return _GetkLeavel(root->_left,k-1)+_GetkLeavel(root->_right,k-1);
}
size_t _Depth(Node* root)
{
if(root==NULL)
return 0;
if(root->_left==NULL&&root->_right==NULL)
return 1;
size_t left=_Depth(root->_left);
size_t right=_Depth(root->_right);
return left>right?left+1:right+1;
}
Node* _Find(Node* root,const T&x)
{
if(root==NULL)
return NULL;
if(root->_data==x)
return root;
Node* ret=_Find(root->_left,x);
if(ret)
return ret;
return _Find(root->_right,x);
}
protected:
Node* _root;
};
void TestBinaryTree()
{
int array[10]={1,2,3,'#','#',4,'#','#',5,6};
BinaryTree<int> t1(array,sizeof(array)/sizeof(array[0]),'#');
t1.PrevOrder();
BinaryTree<int> t2(t1);
t2.PrevOrderNonR();
t1.PrevOrderNonR();
t1.PostOrderNonR();
t1.InOrder();
t1.LevelOrder();
cout<<"Size:"<<t1.Size()<<endl;
cout<<"kLeavel:"<<t1.GetkLeavel(4)<<endl;
cout<<"LeafSize:"<<t1.LeafSize()<<endl;
cout<<"Depth:"<<t1.Depth()<<endl;
}
int main()
{
TestBinaryTree();
return 0;
}