本篇博文主要关注C++数据结构二叉树的简单实现,主要实现二叉树类的构建,包括二叉树的构造、拷贝构造、析构函数、赋值运算符的重载、前序中序后序层序遍历二叉树、查找指定节点、查找节点的总个数等功能函数,主要依靠递归算法完成。
树的结点类型主要是根结点,指向右孩子的指针和指向左孩子的指针。下面是结点的构造函数:
struct BinaryTreeNode
{
BinaryTreeNode* _left;
BinaryTreeNode* _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 size, const T& invalid)
{
size_t index = 0;
_root = MakeBinaryTree(a, size, invalid,index);
}
BinaryTree(const BinaryTree<T>&t)
{
_root = CopyTree(t._root);
}
~BinaryTree()
{
Destroy(_root);
}
BinaryTree<T>& operator=(BinaryTree<T> t)
{
if (this != &t)
{
std::swap(_root, t._root);
}
return *this;
}
protected:
Node* MakeBinaryTree(T* a,size_t size,const T& invalid,size_t & index)
{
Node* root = NULL;
if (index < size && a[index] != invalid)
{
root = new Node(invalid);
root->_data= a[index];
root->_left = MakeBinaryTree(a, size, invalid,++index);
root->_right = MakeBinaryTree(a, size,invalid,++index);
}
return root;
}
}
二叉树的前序遍历:根(当前)结点->左结点->右结点;
中序遍历:左结点->根(当前)结点->右结点;
后序遍历:左结点->右结点->根(当前)结点;代码实现:
void _PrevOrder(Node* _root)
{
Node* aroot = _root;
if (aroot == NULL)
return;
cout << arrot->_data << "";
_PrevOrde(aroot->_left);
_PrevOrde(aroot->_right);
}
void _InOrder(Node* _root)
{
Node* aroot = _root;
if (aroot == NULL)
return;
_InOrder(aroot->_left);
cout << aroot->_data << "";
_InOrder(aroot->_right);
}
void _PostOrder(Node* _root)
{
Node* aroot = _root;
if (aroot == NULL)
return;
_PostOrder(aroot->_left);
_PostOrder(aroot->_right);
cout << aroot->_data << "";
}
层序遍历:就是一层一层的访问二叉树,利用队列可以实现
void LevelOrder()
{
Node* aroot;
queue<Node*> q;
q.push(aroot);
while (!q.empty())
{
Node* top = q.front();
q.pop();
cout << top->_data << "";
if (top->_left)
{
q.push(top->_left);
}
if (top->_right)
{
q.push(top->_right);
}
}
}
其余函数相对简单,以下是源码:
#pragma once
#include<iostream>
#include<stdlib.h>
#include<assert.h>
#include<queue>
#include<stack>
using namespace std;
template <typename 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 size, const T& invalid)
{
size_t index = 0;
_root = MakeBinaryTree(a, size, invalid,index);
}
BinaryTree(const BinaryTree<T>&t)
{
_root = CopyTree(t._root);
}
~BinaryTree()
{
//Destroy(_root);
}
BinaryTree<T>& operator=(BinaryTree<T> t)
{
if (this != &t)
{
std::swap(_root, t._root);
}
return *this;
}
void PrevOrder()//前序遍历
{
cout << "前序:";
_PrevOrder(_root);
cout << endl;
}
void InOrder()//中序遍历
{
cout << "中序:";
_InOrder(_root);
cout << endl;
}
void PostOrder()
{
cout << "后序:";
_PostOrder(_root);
cout << endl;
}
void PrevOrder_NonR()
{
Node* cur = _root;
stack<Node*> s;
if (cur == NULL)
return;
while (cur || !s.empty())
{
while (cur)
{
s.push();
cout << cur->_data << "";
cur = cur->_left;
}
Node* top = s.top();
s.pop();
cur = top->_right;
}
cout << endl;
}
void InOrdere_NonR()
{
Node* cur = _root;
stack<Node*>s;
if (cur == NULL)
rerurn;
while (cur || !s.empty())
{
while (cur)
{
s.push();
cur = cur->_left;
}
Node* top = s.top;
cout << top->_data << "";
s.pop();
cur = top->_right;
}
cout << endl;
}
void PrevOrderNonR()
{
Node* cur = _root;
Node* prev = NULL;
stack<Node*> s;
while (cur || s.empty())
{
while (cur)
{
s.push();
cur = cur->_left;
}
Node* top = s.top();
if (top->_right == NULL || prev == top->_right)
{
cout << top->_data << "";
prev = top;
s.pop();
}
else
{
cur = top->_right;
}
}
cout << endl;
}
void LevelOrder()
{
Node* aroot;
queue<Node*> q;
q.push(aroot);
while (!q.empty())
{
Node* top = q.front();
q.pop();
cout << top->_data << "";
if (top->_left)
{
q.push(top->_left);
}
if (top->_right)
{
q.push(top->_right);
}
}
}
size_t FindKLeves(size_t k)
{
return _FindKLeves(_root, k);
}
size_t FindX(const T&x)
{
return _FindX(_root, x);
}
size_t Size()
{
return _Size(_root);
}
size_t Depth()
{
return _Depth(_root);
}
protected:
Node* _root;
protected:
Node* MakeBinaryTree(T* a,size_t size,const T& invalid,size_t & index)
{
Node* root = NULL;
if (index < size && a[index] != invalid)
{
root = new Node(invalid);
root->_data= a[index];
root->_left = MakeBinaryTree(a, size, invalid,++index);
root->_right = MakeBinaryTree(a, size,invalid,++index);
}
return root;
}
Node* CopyTree(const BinaryTree<T>* _root)
{
if (_root == NULL)
{
return;
}
Node* root = new Node(_root->_data);
root->_left = CopyTree(_root->_left);
root->_right = CopyTree(_root->_right);
return root;
}
void Destroy(Node* root)
{
//Node aroot = _root;
if (root = NULL)
{
return;
}
Destroy(root->_left);
Destroy(root->_right);
delete root;
}
void _PrevOrder(Node* _root)
{
Node* aroot = _root;
if (aroot == NULL)
return;
cout << arrot->_data << "";
_PrevOrde(aroot->_left);
_PrevOrde(aroot->_right);
}
void _InOrder(Node* _root)
{
Node* aroot = _root;
if (aroot == NULL)
return;
_InOrder(aroot->_left);
cout << aroot->_data << "";
_InOrder(aroot->_right);
}
void _PostOrder(Node* _root)
{
Node* aroot = _root;
if (aroot == NULL)
return;
_PostOrder(aroot->_left);
_PostOrder(aroot->_right);
cout << aroot->_data << "";
}
size_t _FindKLeves(Node* _root, size_t k)
{
Node* cur = _root;
if (cur == NULL || k = 0)
return 0;
if (k == 1)
{
return 1;
}
size_t left = _FindKLeves(cur->_left, k - 1);
size_t right = _FindKLeves(cur->_right, k - 1);
return left + right;
}
Node* _FindX(Node* _root, const T& x)
{
Node* ret = NULL;
Node* cur = _root;
if (cur == NULL)
return;
if (cur->_data == x)
{
ret = cur;
}
else
{
ret = _FindX(cur->_left, x);
if (ret == NULL)
{
ret = _FindX(cur->_right, x);
}
}
return ret;
}
size_t _Size(BinaryTreeNode<T>* _root)
{
size_t ret = 0;
if (_root == NULL)
return ret;
ret++;
ret += _Size(_root->_left);
ret += _Size(_root->_right);
}
size_t _Depth(Node* _root)
{
if (_root == NULL)
return;
int left = _Depth(_root->_left) + 1;
int right = _Depth(_root->_right) + 1;
return left > right ? left : right;
}
};
void TestBinaryTree()
{
int a[20] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
BinaryTree<int> t(a, 10, '#');
void PrevOrder();//前序遍历,其余测试可以自行添加。
}