分享

算法1二叉树的遍历方法

 白雪~~~ 2012-03-10
//4.4 二叉树的遍历方法
#define n0 100
struct node
{
int data;
int llink,rlink;
};

node tree[n0+1];
int root; //树的根节点位置


//递归方式实现前序,中序,后序遍历
void preorder(int p)
{
if(!p)
{//如果根节点不为空
cout<<tree[p].data;
preorder(tree[p].llink);
preorder(tree[p].rlink);
}
}

void inorder(int p)
{
if(!p)
{//如果根节点不为空
inorder(tree[p].llink);
cout<<tree[p].data;
inorder(tree[p].rlink);
}
}

void postorder(int p)
{
if(!p)
{//如果根节点不为空
postorder(tree[p].llink);
postorder(tree[p].rlink);
cout<<tree[p].data;
}
}


//非递归算法的前序,中序,后序遍历
//前序列的算法思想 :从二叉树的根节点开始,令指针变量P指向根节点,访问当前节点p,并将p压入栈中。
//然后令p指向当前指向节点的左孩子节点。若p不为空,继续访问当前节点p,并将p压入栈中。如此反复直到p为空
//从栈中弹出栈顶元素赋给指针变量p,并令p指向它的右孩子节点,重复上述过程,当p为空,并且栈也为空时候,遍历结束。
void preorder()
{
int s[n0+1]; //栈
int t; //栈指针
int p = root;//树指针

while(p||t)
{//当p不为空或者栈不为空时
if(p)
{//当期指针不为空时候
cout<<tree[p].data; //访问当前节点
s[++t] = p; //当前地址入栈
p = tree[p].llink; //p指向p的左孩子
}
else
{//如果p指向的p的左孩子为空,就是没有左孩子
p = s[t--];//p返回到它的父亲节点
p = tree[p].rlink; //p指向它的父亲节点的右孩子
}

}
}

//中序算法:和前序算法基本上一致,但是数据访问在出栈的时候
//前序列的算法思想 :从二叉树的根节点开始,令指针变量p指向根节点,访问当前节点p,并将p压入栈中。
//然后令p指向当前指向节点的左孩子节点。若p不为空,继续访问当前节点p,并将p压入栈中。如此反复直到p为空
//从栈中弹出栈顶元素赋给指针变量p,并令p指向它的右孩子节点,重复上述过程,当p为空,并且栈也为空时候,遍历结束。

void preorder()
{
int s[n0+1]; //栈
int t; //栈指针
int p = root;//树指针

while(p||t)
{//当p不为空或者栈不为空时
if(p)
{//当期指针不为空时候
s[++t] = p; //当前地址入栈
p = tree[p].llink; //p指向p的左孩子
}
else
{//如果p指向的p的左孩子为空,就是没有左孩子
p = s[t--];//p返回到它的父亲节点
cout<<tree[p].data; //访问当前节点
p = tree[p].rlink; //p指向它的父亲节点的右孩子
}

}
}

//后序遍历
//算法思路:当遇到非空的二叉树时候,首先将根节点地址和该节点的“右子树没有遍历”标记压入栈,然后沿
//左子数下降去遍历根节点的左子树,当遇到空二叉树时候,也就是这个节点没有左子树了,弹出栈顶元素,
//取得这个节点根节点的位置和,该根节点的右子树是否已经遍历的标记。
//1如果右子树已经遍历,就访问这个根节点。
//2如果右子树没有遍历,就把这个根节点的地址和这个根节点的“右子树已经遍历”的标记,压入栈中。然后沿
//右子树去遍历这个根节点的右子树。
//s[t] > 0 :此节点右子树没有遍历
//s[t] < 0 : 此节点右子树已经遍历

void postorder()
{
int s[n0+1]; //栈
int t = 0; //栈指针
int p = root;//p指向当前节点

while(p||t)
{//当当前指针不为空 或者 栈不为空的时候
if(p)
{//如果当前指针不为空
s[++t] = p ;//同时p>0表示这个节点的右孩子还没有被遍历
p = tree[p].llink; //沿着左孩子向下遍历
}
else
{//如果当期指针为空了,表示栈顶节点的左孩子为空
if(s[t]<0)
{//如果这个栈顶节点的右孩子被访问过了
p = -s[t--]; //出栈,得到当前节点的父亲节点的地址
cout<<tree[p].data; //访问根节点
}
else
{//如果栈顶节点的右孩子没有被访问过
s[t] = -s[t]; //表示栈顶节点的右孩子已经被遍历过了
p = s[t]; //
p = tree[s[t]]->rlink;
}
}
}
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多