在数据处理的过程中,二叉树的大小和形态不会发生剧烈变化的情况下,适合用数组来表示二叉树的抽象数据类型。
完全二叉树一般由数组存储表示,而一般二叉树则是用链表存储表示的。
本篇将采用二叉链的存储方式对二叉树进行存储。
二叉树的创建,使用递归前序构建二叉树。先创建根节点,在对左子树进行创建,左子树创建完成后,又对右子树进行创建。当遇到非法值时表示该子树创建完成。
前序遍历:根节点->左节点->右节点
递归:打印根节点的数据,打印右子树的所有数据,打印左子树的所有数据。
非递归:定义一个栈,将根节点压栈并访问,依次将左子树压栈,左子树同样相当于一棵完整的树,重复此过程。若左子树访问完成,则将最后一个左子树退栈,访问上一个节点的右子树,依次类推,最终将会遍历整个子树。
中序遍历及后序遍历与前序遍历类似,不同的是:
中序遍历先访问左子树,再访问根节点,最后访问右子树。非递归实现中序遍历时,同样将根节点压栈,但是不进行访问,在左子树遍历完成后进行访问。
后序遍历先访问左子树,再访问右子树,最后访问根节点。非递归实现后序遍历时,将根节点压栈,访问左子树,完成后访问右子树,将右子树访问完成后再访问其根节点。
层序遍历使用队列实现。
二叉树的创建,遍历及一些简单操作的代码如下:
template<typename T>
struct BinaryTreeNode //二叉树的节点
{
T _data; //数据
BinaryTreeNode<T>* _left; //左子树
BinaryTreeNode<T>* _right; //右子树
BinaryTreeNode(const T& x) //构造函数
:_data(x)
, _left(NULL)
, _right(NULL)
{
}
};
template<typename T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree() //构造函数
:_root(NULL)
{
}
BinaryTree(T* array, size_t n, const T&invalid = T()) //前序构建二叉树
{
size_t index = 0;
_root = _CreatTreeR(array, n, invalid, index);
}
void PrevOrderR() //用递归的方法前序遍历
{
_PrevOrderR(_root);
cout << endl;
}
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 InOrderR() //用递归的方法中序遍历
{
_InOrderR(_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 PostOrderR() //用递归的方法后序遍历
{
_PostOrderR(_root);
cout << endl;
}
void PostOrderNonR() //非递归前序遍历
{
Node* cur = _root;
stack<Node*> s;
Node* prev = NULL;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
if (top->_right == NULL || top->_right == prev)
{
cout << top->_data << " ";
prev = top;
s.pop();
}
else
{
cur = top->_right;
}
}
cout << endl;
}
void LevelOrder() //层序遍历
{
queue<Node*> q;
if (_root)
{
q.push(_root);
}
while (!q.empty())
{
Node* front = q.front();
cout << front->_data << " ";
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 SizeR() //递归实现求节点个数
//{
// return _SizeR(_root);
//}
size_t SizeR() //递归实现求节点个数
{
size_t count = 0;
return _SizeR(_root, count);
}
size_t GetLeafSizeR() //递归求叶节点个数
{
return _GetLeafSizeR(_root);
}
size_t GetKLeafSizeR(size_t k) //递归求第K层节点个数
{
return _GetKLeafSizeR(_root, k);
}
Node* FindR(const T& x) //递归查找一个数字的位置
{
return _FindR(_root, x);
}
BinaryTree(const BinaryTree<T>& t) //拷贝构造
:_root(NULL)
{
_root = _CopyTreeR(t._root);
}
BinaryTree<T>& operator=(const BinaryTree<T>&t) //赋值运算符重载
{
if (this != &t)
{
Node* root = _CopyTreeR(t._root);
_DestroyR(_root);
_root = root;
}
}
~BinaryTree() //析构函数
{
_DestroyR(_root);
}
protected:
size_t _Depth(Node* root)
{
if (root == NULL)
{
return 0;
}
int left = _Depth(root->_left);
int right = _Depth(root->_right);
return left > right ? left : right;
}
Node* _CopyTreeR(Node* root)
{
Node* head = NULL;
if (root)
{
head = new Node(root->_data);
head->_left = _CopyTreeR(root->_left);
head->_right = _CopyTreeR(root->_right);
}
return head;
}
void _DestroyR(Node* root)
{
Node* del;
Node* cur = root;
if (cur)
{
del = cur;
_DestroyR(cur->_left);
_DestroyR(cur->_right);
delete del;
}
}
Node* _CreatTreeR(T* array, size_t n, const T& invalid, size_t& index)
{
Node* root = NULL;
if (array[index] != invalid && index < n)
{
root = new Node(array[index]);
root->_left = _CreatTreeR(array, n, invalid, ++index);
root->_right = _CreatTreeR(array, n, invalid, ++index);
}
return root;
}
void _PrevOrderR(Node* root)
{
if (root == NULL)
{
return;
}
cout << root->_data << " ";
_PrevOrderR(root->_left);
_PrevOrderR(root->_right);
}
void _InOrderR(Node* root)
{
if (root == NULL)
{
return;
}
_InOrderR(root->_left);
cout << root->_data << " ";
_InOrderR(root->_right);
}
void _PostOrderR(Node* root)
{
if (root == NULL)
{
return;
}
_PostOrderR(root->_left);
_PostOrderR(root->_right);
cout << root->_data << " ";
}
//size_t _SizeR(Node* root)
//{
// if (root == NULL)
// {
// return 0;
// }
// return _SizeR(root->_left) + _SizeR(root->_right) + 1;
//}
size_t _SizeR(Node* root, size_t& count)
{
if (root == NULL)
{
return 0;
}
++count;
_SizeR(root->_left, count);
_SizeR(root->_right, count);
return count;
}
size_t _GetLeafSizeR(Node* root)
{
if (root == NULL)
{
return 0;
}
if (root->_left == NULL && root->_right == NULL)
{
return 1;
}
else
{
return _GetLeafSizeR(root->_left) + _GetLeafSizeR(root->_right);
}
}
size_t _GetKLeafSizeR(Node* cur, size_t k)
{
if (cur == NULL)
{
return 0;
}
if (k == 1)
{
return 1;
}
else
{
return _GetKLeafSizeR(cur->_left, k - 1) + _GetKLeafSizeR(cur->_right, k - 1);
}
}
Node* _FindR(Node* root, const T& x)
{
if (root == NULL)
{
return NULL;
}
if (root->_data == x)
{
return root;
}
Node* cur = _FindR(root->_left, x);
if (cur)
{
return cur;
}
else
{
return _FindR(root->_right, x);
}
}
protected:
Node* _root;
};
测试用例为:
void TestBinaryTree()
{
int array1[10] = { 1,2,3,'#','#',4,'#','#',5,6 };
BinaryTree<int> t1(array1, sizeof(array1) / sizeof(array1[0]), '#');
cout << "t1.PrevOrderR: ";
t1.PrevOrderR();
cout << "t1.PrevOrderNonR: ";
t1.PrevOrderNonR();
cout << "t1.InOrderR: ";
t1.InOrderR();
cout << "t1.InOrderNonR: ";
t1.InOrderNonR();
cout << "t1.PostOrderR: ";
t1.PostOrderR();
cout << "t1.PostOrderNonR: ";
t1.PostOrderNonR();
cout << "t1.LevelOrder: ";
t1.LevelOrder();
cout << "t1.Size: " << t1.SizeR() << endl;
cout << "t1.Depth: " << t1.Depth() << endl;
cout << "t1.K层节点个数: " << t1.GetKLeafSizeR(3) << endl;
cout << "t1.叶节点个数: " << t1.GetLeafSizeR() << endl;
BinaryTree<int> t2(t1);
cout << "t2.PrevOrderR: ";
t2.PrevOrderR();