一、二叉树的遍历操作
对于上图二叉树有以下几种遍历操作
(一)前序(根)遍历
若二叉树为空,则空操作返回;否则:
①访问根结点;
②前序遍历根结点的左子树;
③前序遍历根结点的右子树。
前序遍历序列:A B D G C E F
(二)中序(根)遍历
若二叉树为空,则空操作返回;否则:
①中序遍历根结点的左子树;
②访问根结点;
③中序遍历根结点的右子树。
中序遍历序列:D G B A E C F
(三)后序(根)遍历
若二叉树为空,则空操作返回;否则:
①后序遍历根结点的左子树;
②后序遍历根结点的右子树。
③访问根结点;
后序遍历序列:G D B E F C A
(四)层序遍历
二叉树的层次遍历是指从二叉树的第一层(即根结点)开始,从上至下逐层遍历,在同一层中,则按从左到右的顺序对结点逐个访问。
二、二叉树的顺序存储结构
二叉树的顺序存储结构就是用一维数组存储二叉树中的结点,并且结点的存储位置(下标)应能体现结点之间的逻辑关系——父子关系。
利用数组下标来反映结点之间的逻辑关系
完全二叉树和满二叉树中结点的序号可以唯一地反映出结点之间的逻辑关系 。
前序
void Preorder(int root, char data[]){
if(data[root]!='\0'){
cout<<data[root] ;
Preorder(2*root,data);
Preorder(2*root+1,data);
}
return;
}
中序
void InOrder(int root, char data[]){
if(data[root]!='\0'){
InOrder(2*root,data);
cout<<data[root] ;
InOrder(2*root+1,data);
}
return;
}
后序
void PostOrder(int root, char data[]){
if(data[root]!='\0'){
PostOrder(2*root,data);
PostOrder(2*root+1,data);
cout<<data[root] ;
}
return;
}
三、二叉链表
(一)基本思想:令二叉树的每个结点对应一个链表结点,链表结点除了存放与二叉树结点有关的数据信息外,还要设置指示左右孩子的指针。
(二)结点结构:lchild-data-rchild
其中,data:数据域,存放该结点的数据信息;
lchild:左指针域,存放指向左孩子的指针;
rchild:右指针域,存放指向右孩子的指针。
template <class T>
struct BiNode
{
T data;
BiNode<T> *lchild, *rchild;
};
(三)二叉链表存储结构的结构声明:
template <class T>
class BiTree
{
public:
BiTree();
~BiTree( );
void PreOrder(){PreOrder(root);}
void InOrder() {InOrder(root);}
void PostOrder() {PostOrder(root);}
void LevelOrder(){LeverOrder(root)};
private:
BiNode<T> *root;
BiNode<T> * Creat( );
void Release(BiNode<T> *root);
void PreOrder(BiNode<T> *root);
void InOrder(BiNode<T> *root);
void PostOrder(BiNode<T> *root);
void LevelOrder(BiNode<T> *root);
};
(四)遍历(递归算法):
Eg:前序遍历:
template <class T>
void BiTree::PreOrder(BiNode<T> *root)
{
if (root ==NULL) return;
else {
cout<<root->data;
PreOrder( root->lchild );
PreOrder( root->rchild );
}
}
中序遍历与后序遍历只需改变访问顺序,不再赘述。
(五)遍历(非递归算法)
1、二叉树前序遍历的非递归算法的关键:
在前序遍历过某结点的整个左子树后,如何找到该结点的右子树的根指针。
解决办法:在访问完该结点后,将该结点的指针保存在栈中,以便以后能通过它找到该结点的右子树。
栈是实现递归的最常用的结构
2、思想:
遇到一个结点,就访问该结点,并把此结点推入栈中,然后遍历它的左子树;
遍历完它的左子树后,从栈顶托出这个结点,并按照它的右链接指示的地址再去遍历该结点的右子树结构。
Eg:前序遍历
template <class T>
void BiTree::PreOrder(BiNode<T> *root) {
SeqStack<BiNode<T> *> s; //栈s初始化,循环直到root为空且栈s为空
while (root!=NULL | | !s.empty()) {//当root不空时循环
while (root!= NULL) {
cout<<root->data;//输出root->data
s.push(root);//将指针root的值保存到栈中;
root=root->lchild; //继续遍历root的左子树
}
if (!s.empty()) { //如果栈s不空,则将栈顶元素弹出至root;
root=s.pop();
root=root->rchild; //准备遍历root的右子树;
}
}
}