您的位置:首页 > 编程语言 > C语言/C++

C++实现二叉树的基本操作(递归+非递归)

2017-03-19 21:31 555 查看
关于二叉树的概念不再赘述,看一个简单例子:



下面看代码:

#include <iostream>
#include <assert.h>
#include <stack>
#include <queue>

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
{
public:
typedef BinaryTreeNode<T> Node;

//构造函数
BinaryTree(T* a, size_t n, size_t& index,const T& invalid = T())
{
_root = _CreateTree(a, n, index,invalid);
}

~BinaryTree()
{
_Destory(_root);
}

BinaryTree(const BinaryTree<T>& t)
{
_root=_Copy(t._root);
}

//先序遍历
void PrevOrder()
{
_PrevOrder(_root);
cout << endl;
}
//非递归先序遍历
void PrevOrderNonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)                     //一直进行左子树进入,并将可以访问的结点压栈
{
cout << cur->_data << " ";
s.push(cur);
cur = cur->_left;
}                               //出while循环时,该结点没有左子树了

Node* top = s.top();            //top记录的是最后一个可以走的结点
s.pop();                        //将其出栈
cur = top->_right;              //cur指向该节点的右子树,然后回到第一个while循环当做子问题处理
}
cout << endl;
}

//中序遍历
void InOrder()
{
_InOrder(_root);
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();
cout << top->_data << " ";
s.pop();
cur = top->_right;
}
cout << endl;
}

//后序
void BackOrder()
{
_BackOrder(_root);
cout << endl;
}

//后序非递归
void PostOrderNonR()
{
Node* cur = _root;
Node* prev = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}

Node* top = s.top();

if (NULL == top->_right || prev == top->_right)
{
cout << top->_data << " ";
s.pop();
prev = top;
}

else
cur = top->_right;
}
cout << endl;
}

//层序遍历
void LevelOrder()
{
queue<Node*> q;
if (_root)
q.push(_root);
while (!q.empty())
{
Node* tmp = q.front();
cout << tmp->_data << "  ";
q.pop();
if (tmp->_left)
q.push(tmp->_left);
if (tmp->_right)
q.push(tmp->_right);
}
cout << endl;
}

//计算节点个数
size_t Size()
{
return _Size(_root);
}

//在树中寻找x
Node* Find(const T& x)
{
queue<Node*> q;
if (_root)
q.push(_root);
while (!q.empty())
{
Node* tmp = q.front();
q.pop();
if (x == tmp->_data)
return tmp;
if (tmp->_left)
q.push(tmp->_left);
if (tmp->_right)
q.push(tmp->_right);
}
return NULL;
}

//在树中寻找x(递归法)
Node* FindR(const T& x)
{
return _FindR(_root, x);
}

//计算叶子节点个数
size_t GetLeafSize()
{
size_t count = 0;
return _GetLeafSize(_root, count);
}

size_t GetLeafSize2()
{
return _GetLeafSize2(_root);
}

//求树的深度(从1开始)
size_t Depth()
{
size_t leftdepth = 0;
size_t rightdepth = 0;

return _Depth(_root, leftdepth, rightdepth);
}

//计算第K层叶子节点的个数
size_t GetKLeafSize(size_t k)
{
assert(k > 0);
return _GetKLeafSize(_root,k);
}

//求深度(法2)
size_t Depth2()
{
return _Depth2(_root);
}

protected:
// size_t& index
// 传引用原因:递归栈中,index分别属于不同的栈帧,++index会加在不同的栈帧上的index,
// 递归退层时,index的值会恢复成所退到的递归层中的index
Node* _CreateTree(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 = _CreateTree(a, n, ++index,invalid);
root->_right = _CreateTree(a, n, ++index, invalid);
}
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 _BackOrder(Node* root)
{
if (root == NULL)
return;
_BackOrder(root->_left);
_BackOrder(root->_right);
cout << root->_data << "  ";
}

size_t _Size(Node* root)
{
if (root == NULL)
return 0 ;
return _Size(root->_left) + _Size(root->_right) + 1;
}

size_t _GetLeafSize(Node* root,size_t& count)
{
if (root == NULL)
return 0;
if (root->_left == NULL&&root->_right == NULL)
count++;
_GetLeafSize(root->_left,count);
_GetLeafSize(root->_right,count);
return count;
}

size_t _GetKLeafSize(Node* root,size_t k)
{
if (NULL==root)
{
return 0;
}
if (1 == k)
{
return 1;
}
return _GetKLeafSize(root->_left, k - 1) + _GetKLeafSize(root->_right, k - 1);
}

size_t _Depth(Node* root,size_t& left,size_t& right)
{
if (root == NULL)
return 0;
if (root->_left)
{
left++;
_Depth(root->_left, left, right);
}
if (root->_right)
{
right++;
_Depth(root->_right, left, right);
}
return left > right ? left : right;
}

size_t _Depth2(Node* root)
{
if (NULL == root)
{
return 0;
}
int left = _Depth2(root->_left);
int right = _Depth2(root->_right);
return left > right ? left+1 : right+1;
}

Node* _FindR(Node* root, const T& x)
{
if (NULL == root)
return NULL;
if (x == root->_data)
{
return root;
}
Node* ret = _FindR(root->_left, x);
if (ret)
return ret;
return _FindR(root->_right, x);
}

//后序析构,不用保存当前结点的指针
void _Destory(Node* root)
{
if (NULL == root)
return;
_Destory(root->_left);
_Destory(root->_right);
delete root;
}

Node* _Copy(Node* root)
{
if (NULL == root)
return NULL;
Node* newRoot = new Node(root->_data);
newRoot->_left = _Copy(root->_left);
newRoot->_right = _Copy(root->_right);
return newRoot;
}

protected:
Node* _root;
};

void Test()
{
int a[] = { 1,2,3,'#','#',4,'#','#',5,6 };
size_t index = 0;
BinaryTree<int> t(a, sizeof(a) / sizeof(a[0]), index, '#');
cout << "先序遍历:";
t.PrevOrder();

cout << "非递归先序遍历:";
t.PrevOrderNonR();

cout << "中序遍历:";
t.InOrder();

cout << "非递归中序遍历:";
t.InOrderNonR();

cout << "后序遍历:";
t.BackOrder();

cout << "非递归后序遍历:";
t.PostOrderNonR();
cout << "层序遍历:";
t.LevelOrder();

cout << "结点个数:"<< t.Size() << endl;
BinaryTreeNode<int>* ret = NULL;
ret = t.Find(5);
cout <<"Find 5 : "<< ret->_data << endl;

cout << "计算叶节点个数:"<<t.GetLeafSize() << endl;

cout << "Depth: "<<t.Depth() << endl;

cout << "第 3 层叶节点个数:" << t.GetKLeafSize(3) << endl;

cout << "Depth2:" << t.Depth2() << endl;

ret = t.FindR(5);
cout << "FindR 5 : " << ret->_data << endl;

BinaryTree<int> t2(t);
cout << "t2 先序遍历:";
t2.PrevOrder();

}

int main()
{
Test();
return 0;
}


运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: