二叉树是一棵特殊的树,它最多有两个孩子结点,左孩子和右孩子
1.建立二叉树
二叉树一个结点指针所指向的内容包含三项,该结点的值,指向左孩子的指针和指向右孩子的指针。所以需要建立一个结构体包含这三项内容
struct BinaryTreeNode
{
BinaryTreeNode<T> *_left;//左孩子
BinaryTreeNode<T> *_right;//右孩子
T _data;
BinaryTreeNode(const T& x)
:_left(NULL)
, _right(NULL)
,_data(x)
{}
};
构造二叉树可以使用递归的方法来构造
BinaryTree(T* a, size_t n, T invalid)
{
int index = 0;
_root = CreateTree(a,n,invalid,index);
}
Node* CreateTree(T* a, int n, T invalid, int& 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;
}
2.二叉树创建后要实现一些功能
2.1 前序二叉树(递归)
先访问头结点,再访问左孩子,最后访问右孩子
该图的遍历顺序应为1 2 3 4 5 6 7
void _PrevOrder(Node* root)
{
if (root != NULL)
{
cout << root->_data << " ";//先遍历打印根节点
_PrevOrder(root->_left); //再遍历左子树
_PrevOrder(root->_right); //最后遍历右子树
}
}
2.2 前序二叉树(非递归)
void PrevOrderNonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cout << cur->_data << " ";
cur = cur->_left;
}
Node *top = s.top();
s.pop();
cur = top->_right;
}
cout << endl;
}
2.3 中序二叉树(递归)
遍历顺序应为3 2 4 1 7 6 5
void _InOrder(Node* root)
{
if (root != NULL)
{
_InOrder(root->_left);//先遍历左子树
cout << root->_data << " ";//再遍历打印根节点
_InOrder(root->_right);//最后遍历右子树
}
}
2.4 中序二叉树(非递归)
void InOrderNonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur->_left)
{
s.push(cur);
cur = cur->_left;
}
cout << cur->_data << " ";
Node *top = s.top();
cout << top->_data << " ";
s.pop();
cur = top->_right;
}
cout << endl;
}
2.5 后序二叉树(递归)
遍历顺序应为3 4 2 7 6 5 1
void _PostOrder(Node* root)
{
if (root != NULL)
{
_PostOrder(root->_left);
_PostOrder(root->_right);
cout << root->_data << " ";
}
}
2.6 后序二叉树(非递归)
void PostOrderNonR()
{
if (_root == NULL)
return;
stack<Node*> s;
Node* cur = _root;
Node* previsited = NULL;//前一个遍历的结点
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
cur = top->_right;
if (cur == NULL || cur == previsited)
{
cout << top->_data << " ";
previsited = top;
s.pop();
cur = NULL;
}
}
cout << endl;
}
二叉树的基本功能
#pragma once
#include<iostream>
#include<queue>
#include<assert.h>
#include<stack>
using namespace std;
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode<T> *_left;
BinaryTreeNode<T> *_right;
T _data;
BinaryTreeNode(const T& x)
:_left(NULL)
, _right(NULL)
,_data(x)
{}
};
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree()
:_root(NULL)
{}
BinaryTree(T* a, size_t n, T invalid)
{
int index = 0;
_root = CreateTree(a,n,invalid,index);
}
Node* CreateTree(T* a, int n, T invalid, int& 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;
}
~BinaryTree()
{
_Destory(_root);
}
void PrevOrder()
{
_PrevOrder(_root);
cout << endl;
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
void PostOrder()
{
_PostOrder(_root);
cout << endl;
}
size_t Size()
{
int count = 0;
_Size(_root,count);
return count;
}
size_t GetLeafSize()
{
size_t count = 0;
_GetLeafSize(_root,count);
return count;
}
size_t GetKlevelSize(size_t k)
{
return _GetKlevelSize(_root,k);
}
size_t Depth()
{
return _Depth(_root);
}
Node* Find(const T& x)
{
return _Find(x, _root);
}
void PrevOrderNonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cout << cur->_data << " ";
cur = cur->_left;
}
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->_left)
{
s.push(cur);
cur = cur->_left;
}
cout << cur->_data << " ";
Node *top = s.top();
cout << top->_data << " ";
s.pop();
cur = top->_right;
}
cout << endl;
}
void PostOrderNonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur->_left)
{
s.push(cur);
cur = cur->_left;
}
while (cur->_right)
{
s.push(cur);
cur = cur->_right;
}
cout << cur->_data << " ";
cur = s.top();
s.pop();
cur = cur->_right;
}
cout << endl;
}
void _levelOrder()
{
_levelOrder(_root);
cout << endl;
}
protected:
Node* _root;
void _PrevOrder(Node* root)
{
if (root != NULL)
{
cout << root->_data << " ";
_PrevOrder(root->_left);
_PrevOrder(root->_right);
}
}
void _InOrder(Node* root)
{
if (root != NULL)
{
_InOrder(root->_left);
cout << root->_data << " ";
_InOrder(root->_right);
}
}
void _PostOrder(Node* root)
{
if (root != NULL)
{
_PostOrder(root->_left);
_PostOrder(root->_right);
cout << root->_data << " ";
}
}
size_t _Size(Node* root, int& count) //二插树的结点个数
{
if (root != NULL)
{
count++;
_Size(root->_left,count);
_Size(root->_right,count);
}
return count;
}
size_t _GetLeafSize(Node* root, size_t& count)//叶子结点的个数
{
if (root != NULL)
{
if (root->_left == NULL&&root->_right == NULL)
{
count++;
}
_GetLeafSize(root->_left, count);
_GetLeafSize(root->_right, count);
}
return count;
}
//第K层结点的个数
size_t _GetKlevelSize(Node*root,size_t k)
{
if (root != NULL)
{
if (k == 1)
return 1;
return _GetKlevelSize(root->_left,k-1) + _GetKlevelSize(root->_right,k-1);
}
return 0;
}
//二叉树的深度
size_t _Depth(Node* root)
{
if (root == NULL)
return 0;
int left=_Depth(root->_left)+1;
int right=_Depth(root->_right)+1;
return left > right ? left:right;
}
//查找某一个结点
Node* _Find(const T& x,Node* root)
{
if (root == NULL)
return NULL;
if (root->_data == x)
return root;
Node* left = _Find( x,root->_left);
if (left)
return left;
return _Find(x,root->_right);
}
//删除某个结点
void _Destory(Node* root)
{
if (root == NULL)
return;
_Destory(root->_left);
_Destory(root->_right);
delete root;
}
//层序遍历
void _levelOrder(Node* root)
{
if (root == NULL)
return;
queue<Node*> q;
q.push(root);
while (!q.empty())
{
Node* front = q.front();
cout << front->_data << " ";
if (front->_left!=NULL)
q.push(front->_left);
if (front->_right != NULL)
q.push(front->_right);
q.pop();
}
}
};
void test()
{
int a[] = { 1, 2, 3, '#', '#', 4, '#','#', 5, 6 };
BinaryTree<int> bt((int*)a, 10, '#');
bt.PrevOrder();
bt.InOrder();
bt.PostOrder();
cout << bt.Size() << endl;;
cout << bt.GetLeafSize() << endl;;
cout << bt.GetKlevelSize(4) << endl;
cout << bt.Depth() << endl;
cout << bt.Find(2) << endl;
bt.PrevOrderNonR();
bt.InOrderNonR();
bt.PostOrderNonR();
}