二叉树基础
2016-04-20 17:51
309 查看
二叉树:二叉树是一棵特殊的树,二叉树每个节点最多有两个孩子结点,分别称为左孩子和右孩子。
二叉树节点结构:
测试代码:
二叉树节点结构:
struct BinaryTreeNode { T _data; //数据 BinaryTreeNode<T>* _left; //指向左子树 BinaryTreeNode<T>* _right; //指向右子树 BinaryTreeNode(const T& d) :_data(d) ,_left(NULL) ,_right(NULL) {} };二叉树的创建:
Node* _CreateTree(const T* a, size_t size, size_t& index, const T& invilid) { Node* root = NULL; if(index<size && a[index] != invilid) { root = new Node(a[index]); //创建根节点 root->_left = _CreateTree(a, size, ++index, invilid); //递归实现左子树 root->_right = _CreateTree(a, size, ++index, invilid); //递归实现右子树 } return root; //返回根节点 }前序遍历:
/* 前序遍历:根->左子树->右子树 */ 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); //递归遍历右子树 }后序遍历:
/* 后序遍历:左子树->右子树->根 */ void _PostOrder(Node* root) { if(root == NULL) { return; } _PostOrder(root->_left); //递归遍历左子树 _PostOrder(root->_right); //递归遍历右子树 cout<<root->_data<<" "; //打印根节点数据 }层次遍历:
/* 层次遍历:第一层->最后一层 */ void _LevelOrder(Node* root) { queue<Node*> qt; if(root == NULL) { return; } qt.push(root); //将根节点压到队列中 while(!qt.empty()) { /* 当根节点的左孩子不为空,就说明这一层还没有完全压入队列中 */ if(qt.front()->_left != NULL) { qt.push(qt.front()->_left); //将根节点左子树压到队列中 } /* 当根节点的右孩子不为空,就说明这一层还没有完全压入队列中 */ if(qt.front()->_right != NULL) { qt.push(qt.front()->_right); //将根节点右子树压到队列中 } cout<<qt.front()->_data<<" "; //依次打印节点 qt.pop(); //将打印的节点出队列 } }二叉树节点的个数 = 就是左子树节点个数加上右子树节点的个数再加上根节点
size_t _Size(Node* root) { if(root == NULL) { return 0; } return _Size(root->_left)+_Size(root->_right)+1;//左子树节点+右子树节点+根节点 }二叉树的深度 = 左子树 >= 右子树 ? 左子树+1, 右子树+1;
size_t _Depth(Node* root) { if(root == NULL) { return 0; } size_t LeftDepth = _Depth(root->_left); size_t RightDepth = _Depth(root->_right); if(LeftDepth >= RightDepth) { return LeftDepth+1; } else { return RightDepth+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); }整体代码:
#include <iostream>测试结构:
#include <queue>
using namespace std;
template <class T>
struct BinaryTreeNode
{
T _data; //数据域
BinaryTreeNode<T>* _left; //指向左子树
BinaryTreeNode<T>* _right; //指向右子树
BinaryTreeNode(const T& d)
:_data(d)
,_left(NULL)
,_right(NULL)
{}
};
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node; //类型重命名,方便后面使用
public:
BinaryTree()
:_root(NULL)
{}
BinaryTree(const T* a, size_t size, const T& invilid)
:_root(NULL)
{
size_t index = 0;
_root = _CreateTree(a, size, index, invilid);
}
BinaryTree<T>(const BinaryTree& tree)
{
_root = _Copy(tree._root);
}
BinaryTree& operator= (BinaryTree tree) //现代式写法
{
swap(_root, tree._root);
return *this;
}
~BinaryTree()
{
if(_root != NULL)
{
_Destroy(_root);
}
}
public:
void PrevOrder()
{
_PrevOrder(_root);
cout<<endl;
}
void InOrder()
{
_InOrder(_root);
cout<<endl;
}
void PostOrder()
{
_PostOrder(_root);
cout<<endl;
}
void LevelOrder()
{
_LevelOrder(_root);
cout<<endl;
}
size_t Size()
{
return _Size(_root);
}
size_t Depth()
{
return _Depth(_root);
}
size_t LeafSize()
{
return _LeafSize(_root);
}
protected:
size_t _Size(Node* root)
{
if(root == NULL)
{
return 0;
}
/* 左子树节点+右子树节点+根节点 */
return _Size(root->_left)+_Size(root->_right)+1;
}
size_t _Depth(Node* root) { if(root == NULL) { return 0; } size_t LeftDepth = _Depth(root->_left); size_t RightDepth = _Depth(root->_right); if(LeftDepth >= RightDepth) { return LeftDepth+1; } else { return RightDepth+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);
}
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); //递归遍历右子树 }
/* 后序遍历:左子树->右子树->根 */ void _PostOrder(Node* root) { if(root == NULL) { return; } _PostOrder(root->_left); //递归遍历左子树 _PostOrder(root->_right); //递归遍历右子树 cout<<root->_data<<" "; //打印根节点数据 }
/* 层次遍历:第一层->最后一层 */
void _LevelOrder(Node* root)
{
queue<Node*> qt;
if(root == NULL)
{
return;
}
qt.push(root);
while(!qt.empty())
{
if(qt.front()->_left != NULL)
{
qt.push(qt.front()->_left);
}
if(qt.front()->_right != NULL)
{
qt.push(qt.front()->_right);
}
cout<<qt.front()->_data<<" ";
qt.pop();
}
}
protected:
Node* _Copy(Node* root)
{
if(root == NULL)
{
return NULL;
}
Node* NewRoot = new Node(root->_data); //创建新的根节点
Node* NewCur = NewRoot;
NewCur->_left = _Copy(root->_left);
NewCur->_right = _Copy(root->_right);
return NewRoot;
}
void _Destroy(Node* root)
{
if(root == NULL)
{
return;
}
if(root->_left == NULL && root->_right == NULL)
{
delete root;
root = NULL;
return;
}
_Destroy(root->_left);
_Destroy(root->_right);
}
Node* _CreateTree(const T* a, size_t size, size_t& index, const T& invilid)
{
Node* root = NULL;
if(index<size && a[index] != invilid)
{
root = new Node(a[index]); //创建根节点
root->_left = _CreateTree(a, size, ++index, invilid);//递归实现左子树
root->_right = _CreateTree(a, size, ++index, invilid);//递归实现右子树
}
return root; //返回根节点
}
protected:
Node* _root; //根节点
};
int main()
{
Test();
system("pause");
return 0;
}
测试代码:
void Test() { int array[10] = {1, 2, 3, '#', '#', 4, '#' , '#', 5, 6}; BinaryTree<int> tree(array, 10, '#'); tree.PrevOrder(); tree.InOrder(); tree.PostOrder(); tree.LevelOrder(); BinaryTree<int> tree2(tree); tree2.PrevOrder(); BinaryTree<int> tree3 = tree2; tree3.PrevOrder(); }测试结果:
相关文章推荐
- AVL树-自平衡二叉查找树(Java实现)
- 有关数据库SQL递归查询在不同数据库中的实现方法
- C#中的递归APS和CPS模式详解
- WinForm实现按名称递归查找控件的方法
- 使用SqlServer CTE递归查询处理树、图和层次结构
- C#中的尾递归与Continuation详解
- C语言二叉树的非递归遍历实例分析
- 使用C语言构建基本的二叉树数据结构
- 一波二叉树遍历问题的C++解答实例分享
- C#递归实现显示文件夹及所有文件并计算其大小的方法
- 举例讲解C语言程序中对二叉树数据结构的各种遍历方式
- C++非递归队列实现二叉树的广度优先遍历
- php递归创建目录的方法
- C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法
- PHP递归创建多级目录
- Javascript递归打印Document层次关系实例分析
- oracle 使用递归的性能提示测试对比
- 使用curl递归下载软件脚本分享
- Perl脚本实现递归遍历目录下的文件
- JavaScript的递归之递归与循环示例介绍