二叉树的创建及遍历
Posted Luella_G
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的创建及遍历相关的知识,希望对你有一定的参考价值。
在数据处理的过程中,二叉树的大小和形态不会发生剧烈变化的情况下,适合用数组来表示二叉树的抽象数据类型。
完全二叉树一般由数组存储表示,而一般二叉树则是用链表存储表示的。
本篇将采用二叉链的存储方式对二叉树进行存储。
二叉树的创建,使用递归前序构建二叉树。先创建根节点,在对左子树进行创建,左子树创建完成后,又对右子树进行创建。当遇到非法值时表示该子树创建完成。
前序遍历:根节点->左节点->右节点
递归:打印根节点的数据,打印右子树的所有数据,打印左子树的所有数据。
非递归:定义一个栈,将根节点压栈并访问,依次将左子树压栈,左子树同样相当于一棵完整的树,重复此过程。若左子树访问完成,则将最后一个左子树退栈,访问上一个节点的右子树,依次类推,最终将会遍历整个子树。
中序遍历及后序遍历与前序遍历类似,不同的是:
中序遍历先访问左子树,再访问根节点,最后访问右子树。非递归实现中序遍历时,同样将根节点压栈,但是不进行访问,在左子树遍历完成后进行访问。
后序遍历先访问左子树,再访问右子树,最后访问根节点。非递归实现后序遍历时,将根节点压栈,访问左子树,完成后访问右子树,将右子树访问完成后再访问其根节点。
层序遍历使用队列实现。
二叉树的创建,遍历及一些简单操作的代码如下:
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();
以上是关于二叉树的创建及遍历的主要内容,如果未能解决你的问题,请参考以下文章