下面代码所用到的测试用例画成树的样子长这样:
创建树时给的是数组,用‘#’代表非法值,即该结点为空。
二叉树的递归实现:
#pragma once
#include<iostream>
#include<queue>
using namespace std;
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode(T value=0)
:_value(value), _left(NULL), _right(NULL)
{}
T _value;
BinaryTreeNode<T>* _left;
BinaryTreeNode<T>* _right;
};
template<class T>
class BinaryTree
{
public:
typedef BinaryTreeNode<T> Node;
BinaryTree()
{}
BinaryTree(T* a, size_t size, const T& invalid)
{
size_t index = 0;
_root=_CreatTree( a, size,index, invalid);
}
BinaryTree(const BinaryTree<T>& bt)
{
_root = _Copy(bt._root);
}
BinaryTree<T>& operator=(BinaryTree<T>& bt)
{
if (this != &bt)
{
BinaryTree<T> tmp(bt);
swap(tmp._root, _root);
}
}
~BinaryTree()
{
_Distory(_root);
}
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);
}
size_t GetKLevel(size_t k) //第K层结点个数
{
}
protected:
Node* _Distory(Node* root)
{
if (root)
{
_Distory(root->_left);
_Distory(root->_right);
Node* del = root;
delete del;
}
return root;
}
Node* _CreatTree( T*a, size_t size,size_t& index,const T& invalid)
{
Node* root = NULL;
if ((index < size)&&(a[index] != invalid))
{
root = new Node(a[index]);
root->_left = _CreatTree(a, size, ++index, invalid);
root->_right = _CreatTree(a, size, ++index, invalid);
}
return root;
}
Node* _Copy(Node* copyroot)
{
Node* root = NULL;
if (copyroot!=NULL)
{
root = new Node(copyroot->_value);
root->_left = _Copy(copyroot->_left);
root->_right = _Copy(copyroot->_right);
}
return root;
}
Node* _PrevOrder(Node* root)
{
if (root)
{
cout << root->_value << " ";
_PrevOrder(root->_left);
_PrevOrder(root->_right);
}
return root;
}
Node* _InOrder(Node* root)
{
if (root)
{
_InOrder(root->_left);
cout << root->_value<<" ";
_InOrder(root->_right);
}
return root;
}
Node* _PostOrder(Node* root)
{
if (root)
{
_PostOrder(root->_left);
_PostOrder(root->_right);
cout << root->_value << " ";
}
return root;
}
void _LevelOrder(Node* root)
{
queue<Node*> q;
q.push(root);
while (!q.empty())
{
Node* tmp = q.front();
cout << tmp->_value<<" ";
if (tmp->_left)
q.push(tmp->_left);
if (tmp->_right)
q.push(tmp->_right);
q.pop();
}
}
size_t _Size(Node* root)
{
size_t size = 0;
if (root)
{
size = _Size(root->_left) + _Size(root->_right)+1;
}
return size;
}
size_t _Depth(Node* root)
{
size_t depth1 = 0;
size_t depth2 = 0;
if (root)
{
depth1 = _Depth(root->_left) + 1;
depth2 = _Depth(root->_right) + 1;
}
return depth1 > depth2 ? depth1 : depth2;
}
size_t _LeafSize(Node* root)
{
if (root == NULL)
return 0;
else if (root->_left == NULL&&root->_right == NULL)
return 1;
return _LeafSize(root->_left) + _LeafSize(root->_right);
}
private:
Node* _root;
};
void test()
{
int array[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
int array1[15] = { 1, 2, '#', 3, '#', '#', 4, 5, '#', 6, '#', 7, '#', '#', 8 };
BinaryTree<int> bt(array, 10, '#');
bt.PrevOrder();
bt.InOrder();
bt.PostOrder();
cout << bt.Size() << endl;
cout << bt.Depth() << endl;
cout << bt.LeafSize() << endl;
BinaryTree<int> bt2(array1, 15, '#');
cout << bt2.Depth() << endl;
cout << bt2.LeafSize() << endl;
BinaryTree<int> bt3(bt);
bt3.PrevOrder();
BinaryTree<int> bt4=bt3;
bt4.PrevOrder();
bt4.LevelOrder();
}递归的好处在于代码简练。但递归不容易理解。
非递归的二叉树(面试经常会考的):
#pragma once
#include<iostream>
#include<cassert>
#include<queue>
#include<stack>
using namespace std;
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode(T value = 0)
:_value(value), _left(NULL), _right(NULL)
{}
T _value;
BinaryTreeNode<T>* _left;
BinaryTreeNode<T>* _right;
};
template<class T>
class BinaryTree
{
public:
typedef BinaryTreeNode<T> Node;
BinaryTree()
{}
explicit BinaryTree(T* a, size_t size, const T& invalid) //构造函数,创建一棵树。
{
stack<Node*> s;
size_t index = 0;
Node* cur = NULL;
while (index < size)
{
while ((index < size) && (a[index] != invalid))
{
if (index == 0)
{
_root = new Node(a[index++]);
cur = _root;
}
else
{
cur->_left = new Node(a[index++]);
cur = cur->_left;
}
s.push(cur);
}
index++;
Node* top = s.top();
s.pop();
if ((index < size) && (a[index] != invalid))
{
cur = top;
cur->_right = new Node(a[index++]);
cur = cur->_right;
s.push(cur);
}
}
}
BinaryTree(const BinaryTree<T>& bt) //拷贝构造
{
Node* cur = bt._root;
Node* root = NULL;
stack<Node*>s;
stack<Node*>s1;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
if (root == NULL)
{
root = new Node(cur->_value);
_root = root;
}
else
{
root->_left = new Node(cur->_value);
root = root->_left;
}
cur = cur->_left;
s1.push(root);
}
Node* top = s.top();
Node* top1 = s1.top();
s.pop();
s1.pop();
cur = top->_right;
if (cur)
{
root = top1;
root->_right = new Node(cur->_value);
root = root->_right;
cur = cur->_left;
}
}
}
BinaryTree<T>& operator=(BinaryTree<T> bt)
{
swap(_root, bt._root);
return *this;
}
void PrevOrderNoR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
cout << cur->_value << " ";
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
s.pop();
cur = top->_right;
}
cout << endl;
}
void InOrderNoR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
s.pop();
cout << top->_value << " ";
cur = top->_right;
}
cout << endl;
}
void PostOrderNoR()
{
Node* cur = _root;
Node* prev = NULL;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
if ((top->_right == NULL) || (prev == top->_right))
{
prev = top;
cout << top->_value << " ";
s.pop();
//cur = top->_right;
}
else
cur = top->_right;
}
cout << endl;
}
size_t SizeNoR()
{
size_t size = 0;
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
size++;
cur = cur->_left;
}
Node* top = s.top();
s.pop();
cur = top->_right;
}
return size;
}
size_t DepthNoR()
{
if (_root == NULL)
return 0;
size_t depth = 0;
Node* cur = NULL;
queue<Node*> q;
size_t VisitNum = 0; //有多少数据出栈
size_t NodeNum = 1;
size_t LeveNum = 1; //每一层最后一个数据的序号
q.push(_root);
while (!q.empty())
{
cur = q.front();
q.pop();
VisitNum++;
if (cur->_left)
{
NodeNum++;
q.push(cur->_left);
}
if (cur->_right)
{
NodeNum++;
q.push(cur->_right);
}
if (LeveNum == VisitNum)
{
depth++;
LeveNum = NodeNum;
}
}
return depth;
}
size_t LeveNum() //叶子节点个数
{
size_t count = 0;
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
if ((cur->_left == NULL) && (cur->_right == NULL))
count++;
cur = cur->_left;
}
Node* top = s.top();
s.pop();
cur = top->_right;
}
return count;
}
size_t GetKLeve(size_t k) //得到第k层结点个数。
{
assert(k <= DepthNoR());
if (k == 1)
return 1;
queue<Node*>q;
size_t NodeNum = 1;
size_t LeveNum = 1;
size_t VisitNum = 0;
size_t leve = 1;
q.push(_root);
while (!q.empty())
{
Node* cur = q.front();
q.pop();
VisitNum++;
if (cur->_left)
{
q.push(cur->_left);
NodeNum++;
}
if (cur->_right)
{
q.push(cur->_right);
NodeNum++;
}
if (LeveNum == VisitNum)
{
leve++;
if (leve == k)
break;
LeveNum = NodeNum;
}
}
return NodeNum - VisitNum;
}
private:
Node* _root;
};
void test()
{
int array[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
BinaryTree<int> bt(array, 10, '#');
bt.PrevOrderNoR();
bt.InOrderNoR();
bt.PostOrderNoR();
BinaryTree<int> bt1(bt);
bt1.PrevOrderNoR();
BinaryTree<int> bt2 = bt1;
bt2.PrevOrderNoR();
cout << bt.SizeNoR() << endl;
cout << bt.DepthNoR() << endl;
cout << bt.LeveNum() << endl;
cout << bt.GetKLeve(3) << endl;
}可以看到,非递归相对来说代码量能多点,但是比较容易理解,而且几个遍历过程代码十分相似,理解其中一个,后面几个都是类似的。
二叉树遍历与操作

本文介绍了一种使用递归和非递归方法实现二叉树遍历及操作的方法。通过具体的代码示例,详细解释了前序、中序、后序遍历等基本操作,并提供了树的创建、复制、销毁等高级功能。
4004

被折叠的 条评论
为什么被折叠?



