您的位置:首页 > 其它

二叉树的遍历算法实现、以及所有简单操作

2017-03-19 21:40 429 查看
二叉树的遍历分为先序遍历,中序遍历,后序遍历,层序遍历

先序遍历:根节点->左子树->右子树

       递归思想:判断根节点是否为空,若不为空则打印根节点数据,然后调用函数取根节点左子树的数据,然后再调用函数取右子树的数据。

      递归实现:

void PrevOrder() //前序遍历
{
cout << "前序遍历为:";
_PrevOrder(_root);
cout << endl;
}
void _PrevOrder(Node* root)  //根->左子树->右子树
{
if (root == NULL)
return;

cout << root->_value << " ";
_PrevOrder(root->_left);
_PrevOrder(root->_right);

}

非递归思想:定义一个栈q,定义一个节点p指针指向根节点;将p压入栈后,取该节点的值,并且让p=p的左子树同时压入q栈中,直到左子树为空,这个时候取栈的栈顶元素,然后删除栈顶元素,并将p节点设置为根节点的右子树节点。让其再重复其上述操作。

简单流程图:



非递归实现:

void PrevOrder_NonR()
{
stack<Node*> q;
Node* p = _root;
while (p != NULL || !q.empty())
{
while (p != NULL)
{
q.push(p);
cout << p->_value << " ";
p = p->_left;
}
Node* node = q.top();
q.pop();
p = node->_right;
}
cout << endl;
}中序遍历:
递归实现:

void InOrder()//中序遍历
{
cout << "中序遍历为:";
_InOrder(_root);
cout << endl;
}
void _InOrder(Node* root)//左子树->根节点->右子树
{
if (root == NULL)
return;

_InOrder(root->_left);
cout << root->_value << " ";
_InOrder(root->_right);
}
非递归想法: 定义一个栈,定义一个节点p指针指向根节点,然后将这个树的所有左子树压入栈中,然后取其栈顶的元素,然后将栈顶pop掉,让p=栈顶节点的右子树,然后重复上面的步骤。
非递归实现:

void InOrder_NonR()
{
stack<Node*> q;
Node* p = _root;
while (p != NULL || !q.empty())
{
while (p != NULL)
{
q.push(p);
p = p->_left;
}

Node* node = q.top();
cout << node->_value << " ";
q.pop();
p = node->_right;
}
cout << endl;
}
后序遍历:
递归实现:

void PostOrder()//后序遍历
{
cout << "后序遍历为:";
_PostOrder(_root);
cout << endl;
}
void _PostOrder(Node* root)//左子树->右子树->根节点
{
if (root == NULL)
return;

_PostOrder(root->_left);
_PostOrder(root->_right);
cout << root->_value << " ";
}


非递归实现:定义一个栈,定义一个节点指针p指向树的根节点;再定义一个节点指针prev指向上次所访问的指针,如果栈不为空或者节点p不等于NULL;则将该树的所有左子树压入栈中,然后取栈顶元素,如果这个栈顶元素的右子树为空或者是上次访问的指针,那么说明这个栈顶元素的左右子树已经遍历了,那么就打印该元素节点的数据,如果这个栈顶元素的右子树不为空或者是不是上次访问的指针,那么就让p指向栈顶元素的右子树,然后重复上述操作。
void PostOrder_NonR()
{
stack<Node*> s;
Node* p = _root;
Node* prev = NULL;
while (p != NULL || !s.empty())
{
while (p != NULL)
{
s.push(p);
p = p->_left;
}
Node* node = s.top();
if (node->_right == NULL || prev == node->_right)
{
cout <<node->_value << " ";
s.pop();
prev = node;
}
else
{
p = node->_right;
}
}
cout << endl;
}

层序遍历:
void LevelOrder() //层序遍历
{
cout << "层序遍历为:";
if (_root != NULL)
{
queue<Node*> q;
q.push(_root);

while (!q.empty())
{
Node* front = q.front();
cout << front->_value << " ";
q.pop();

if (front->_left)
q.push(front->_left);
if (front->_right)
q.push(front->_right);
}
}
cout << endl;
}

计算深度算法:
size_t Depth() //计算树的深度
{
return _Depth(_root);
}
size_t _Depth(Node* root)
{
if (root == NULL)
return 0;
size_t left = _Depth(root->_left);
size_t right = _Depth(root->_right);
if (left > right)
{
return (left + 1);
}
return (right + 1);
}

计算节点算法:

size_t Size() //统计结点数量
{
return _Size(_root);
}
size_t _Size(Node* root)
{
if (root == NULL)
return 0;

return _Size(root->_left) + _Size(root->_right) + 1;
}

计算叶节点算法:

size_t LeafSize() //统计叶结点的数量
{
return _LeafSize(_root);
}
size_t _LeafSize(Node* root)
{
size_t count = 0;
if (root == NULL)
return 0;

if (root->_left == NULL && root->_right == NULL)
return 1;
else
return _LeafSize(root->_left) + _LeafSize(root->_right);
}

计算满结点算法:

size_t FullSize()//计算满二叉树的结点个数
{
return _FullSize(_root);
}
size_t _FullSize(Node* root)
{
if (root == NULL)
return 0;
else if (root->_left == NULL && root->_right == NULL)
return 0;
else if (root->_left != NULL && root->_right == NULL)
return _FullSize(root->_left);
else if (root->_left == NULL && root->_right != NULL)
return _FullSize(root->_right);
else if (root->_left != NULL && root->_right != NULL)
return _FullSize(root->_left) + _FullSize(root->_right) + 1;
}

寻找节点算法:

Node* Find(const size_t& x)
{
return _Find(_root,x);
}
Node* _Find(Node* root,const size_t& x )
{
if (root == NULL)
reutrn NULL;

if (root->_value == x)
return root;

Node* ret = _Find(root->_left, x);
if (ret != NULL)
return ret;

return _Find(root->_right, x);
}


求K层节点数算法:

size_t GetKleve(size_t K) //获取K层结点个数
{
return _GetKleve(_root, K);
}
size_t _GetKleve(Node* root, size_t K)
{
assert(K > 0);
if (root == NULL)
return 0;
if (K == 1)
return 1;
return _GetKleve(root->_left, K - 1) + _GetKleve(root->_right, K - 1);
}

全部代码实现:
#include<iostream>
using namespace std;
#include<queue>
#include<stack>
#include<assert.h>
template<class T>
struct binarytreeNode
{
T _value;
binarytreeNode<T>* _left; //左子树
binarytreeNode<T>* _right; //右子树
binarytreeNode(const T& value)
:_value(value)
, _left(NULL)
, _right(NULL)
{}
};

template<class T>
class binarytree
{
typedef binarytreeNode<T> Node;
public:
binarytree()
:_root(NULL)
{}
binarytree(T* arr, size_t n, const T& invalid = T())
{
size_t index = 0;
_root = _Greatree(arr, n, invalid, index);
}
~binarytree()
{
_Destory(_root);
}
binarytree(const binarytree<T>& t)
{
_root = Copy(t._root);
}

binarytree<T>& operator=(const binarytree<T>& t)
{
if (this != t)
{
Node* newNode = Copy(t._root);
_Destory(_root);
_root = newNode;
}
return *this;
}
void PrevOrder() //前序遍历
{
cout << "前序遍历为:";
_PrevOrder(_root);
cout << endl;
}
void PrevOrder_NonR()
{
stack<Node*> q;
Node* p = _root;
while (p != NULL || !q.empty())
{
while (p != NULL)
{
q.push(p);
cout << p->_value << " ";
p = p->_left;
}
Node* node = q.top();
q.pop();
p = node->_right;
}
cout << endl;
}

void InOrder()//中序遍历
{
cout << "中序遍历为:";
_InOrder(_root);
cout << endl;
}

void InOrder_NonR()
{
stack<Node*> q;
Node* p = _root;
while (p != NULL || !q.empty())
{
while (p != NULL)
{
q.push(p);
p = p->_left;
}

Node* node = q.top();
cout << node->_value << " ";
q.pop();
p = node->_right;
}
cout << endl;
}
void PostOrder()//后序遍历
{
cout << "后序遍历为:";
_PostOrder(_root);
cout << endl;
}
void PostOrder_NonR()
{
stack<Node*> s;
Node* p = _root;
Node* prev = NULL;
while (p != NULL || !s.empty())
{
while (p != NULL)
{
s.push(p);
p = p->_left;
}
Node* node = s.top();
if (node->_right == NULL || prev == node->_right)
{
cout <<node->_value << " ";
s.pop();
prev = node;
}
else
{
p = node->_right;
}
}
cout << endl;
}
void LevelOrder() //层序遍历
{
cout << "层序遍历为:";
if (_root != NULL)
{
queue<Node*> q;
q.push(_root);

while (!q.empty())
{
Node* front = q.front();
cout << front->_value << " ";
q.pop();

if (front->_left)
q.push(front->_left);
if (front->_right)
q.push(front->_right);
}
}
cout << endl;
}

size_t Size() //统计结点数量
{
return _Size(_root);
}

size_t Depth() //计算树的深度
{
return _Depth(_root);
}

size_t LeafSize() //统计叶结点的数量
{
return _LeafSize(_root);
}

size_t FullSize()//计算满二叉树的结点个数
{
return _FullSize(_root);
}

size_t GetKleve(size_t K) //获取K层结点个数
{
return _GetKleve(_root, K);
}
Node* Find(const size_t& x)
{
return _Find(_root,x);
}

protected:
void _PrevOrder(Node* root) //根->左子树->右子树 { if (root == NULL) return; cout << root->_value << " "; _PrevOrder(root->_left); _PrevOrder(root->_right); }
void _InOrder(Node* root)//左子树->根节点->右子树
{
if (root == NULL)
return;

_InOrder(root->_left);
cout << root->_value << " ";
_InOrder(root->_right);
}
void _PostOrder(Node* root)//左子树->右子树->根节点 { if (root == NULL) return; _PostOrder(root->_left); _PostOrder(root->_right); cout << root->_value << " "; }
size_t _Size(Node* root) { if (root == NULL) return 0; return _Size(root->_left) + _Size(root->_right) + 1; }

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

size_t _FullSize(Node* root) { if (root == NULL) return 0; else if (root->_left == NULL && root->_right == NULL) return 0; else if (root->_left != NULL && root->_right == NULL) return _FullSize(root->_left); else if (root->_left == NULL && root->_right != NULL) return _FullSize(root->_right); else if (root->_left != NULL && root->_right != NULL) return _FullSize(root->_left) + _FullSize(root->_right) + 1; }
size_t _GetKleve(Node* root, size_t K) { assert(K > 0); if (root == NULL) return 0; if (K == 1) return 1; return _GetKleve(root->_left, K - 1) + _GetKleve(root->_right, K - 1); }

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

Node* _Find(Node* root,const size_t& x ) { if (root == NULL) reutrn NULL; if (root->_value == x) return root; Node* ret = _Find(root->_left, x); if (ret != NULL) return ret; return _Find(root->_right, x); }
Node* _Greatree(T* arr, size_t n,const T& invalid , size_t& index)
{
Node * node = NULL;
if (arr[index] != invalid && index < n)
{
node = new Node(arr[index]);
node->_left = _Greatree(arr, n, invalid, ++index);
node->_right = _Greatree(arr, n, invalid, ++index);
}

return node;
}
Node* Copy(Node* root)
{
if (root == NULL)
return NULL;
Node* newNode = new Node(root->_value);
newNode->_left = Copy(root->_left);
newNode->_right = Copy(root->_right);

return newNode;
}
void _Destory(Node* root)
{
if (root == NULL)
return;

_Destory(root->_left);
_Destory(root->_right);

delete root;
}
private:
Node* _root;
};
测试用例:
void Text()
{
int array[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
binarytree<int> a(array, sizeof(array) / sizeof(array[0]), '#');
a.PrevOrder();
a.PrevOrder_NonR();
a.InOrder();
a.InOrder_NonR();
a.PostOrder();
a.PostOrder_NonR();
a.LevelOrder();
cout << a.Size() << endl;
cout << a.LeafSize() << endl;
cout << a.Depth() << endl;
cout << a.FullSize() << endl;

cout << a.GetKleve(1) << endl;
cout << a.GetKleve(2) << endl;
cout << a.GetKleve(3) << endl;
binarytree<int> b(a);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树 遍历 算法
相关文章推荐