树的定义:n个节点构成的有限的集合;具有如下的特性:
有一个称为“root(根)”的特殊节点
其余可分为m个互不相交的有限集T1,T2,...Tm;其中每个集合又是一棵树,称为子树。
二叉树定义:一个有穷的结点集合
可以为空;若不为空则由根结点和称为其左子树和右子树的两个不相交的二叉树组成。
二叉树链式存储
结点的结构体定义:
template <typename T>
using TNode = struct TreeNode<T>;
template <typename T>
struct TreeNode {
T data;
TNode<T> *pLeftNode;
TNode<T> *pRightNode;
}
遍历二叉树-先左分支后右分支的方式
template <typename T>
void treeTraversal(TNode<T> *head) {
std::queue<TNode<T> *> tQueue;
TNode<T> *tmpNode = head;
tQueue.push_back(head);
while (tmpNode && !tQueue.empty()) {
while(tmpNode) {
tQueue.push_back(tmpNode); //push的入口只有一个
tmpNode = tmpNode->pLeftNode; //充分地利用其nullptr的特性
}
tmpNode = tQueue.front();
tQueue.pop();
std::cont << tmpNode.data << std::endl;
tmpNode = tmpNode->pRightNode; //充分地利用其nullptr的特性
}
}
遍历二叉树-层序的方式
template <typename T>
void treeTraverse(TNode<T> *head) {
if (!head) return;
std::queue<TNode<T> *> tQueue;
TNode<T> *tmp;
tQueue.push_back(head);
while(!tQueue.empty()) {
tmp = tQueue.front();
tQueue.pop();
std::cout << tmp.data << std::endl;
if (tmp->pLeftNode) tQueue.push_back(tmp->pLeftNode);
if (tmp->pRightNode) tQueue.push_back(tmp->pRightNode);
}
}
上面两种遍历的方式都采用队列这种容器,采用二维树数据结构到一维队列数据结构的转换,第二种遍历方式理解起来更加容易。