版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lingling_nice/article/details/80968006
#include<malloc.h>
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
typedef char ElemType;
typedef struct BtNode
{
BtNode *leftchild;
BtNode *rightchild;
ElemType data;
}BtNode,*BinaryTree;
先序遍历(非递归)
非递归就是利用栈的特性(先进后出),来进行模拟栈void NicePreOrder(BtNode *p)
{
BtNode *s = NULL;
stack<BtNode* > st;
st.push(p);
while(!st.empty())
{
BtNode *node = st.top();st.pop();
cout<<node->data<<" ";
if( node->rightchild != NULL)
{
st.push(node->rightchild);
if(node->leftchild != NULL)
{
st.push(node->leftchild);
}
}
}
cout<<endl;
}
中序遍历(非递归)
//中序遍历
void NiceMiOrder(BtNode *p)
{
BtNode *s = NULL;
stack<BtNode* > st;
while(p != NULL || !st.empty())
{
while(p != NULL)
{
st.push(p);
p = p->leftchild;
}
BtNode *node = st.top();st.pop();
cout<<node->data<<" ";
p = node->rightchild;
}
cout<<endl;
}
后序遍历(非递归)
方法一:
//后序遍历
//后序遍历递归定义:先左子树,后右子树,再根节点。
//后序遍历的难点在于:需要判断上次访问的节点是位于左子树,还是右子树。
//若是位于左子树,则需跳过根节点,先进入右子树,再回头访问根节点;
//若是位于右子树,则直接访问根节点。
void NiceLaOrder(BtNode *p)
{
BtNode *s = NULL;
stack<BtNode *> st;
BtNode *tag = NULL;
while(p != NULL || !st.empty())
{
while(p != NULL)
{
st.push(p);
p = p->leftchild;
}
BtNode *node = st.top();st.pop();
if(node->rightchild == NULL || node->rightchild == tag)
{
cout<<node->data<<" ";
tag = node;
node = NULL;///////////////
}
else
{
st.push(node);
p = node->rightchild;
}
}
cout<<endl;
}
方法二:
//要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。
//如果P不存在左孩子和右孩子,则可以直接访问它;
//或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。
//若非上述两种情况,则将P的右孩子和左孩子依次入栈
//这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问
//左孩子和右孩子都在根结点前面被访问。
void nice_last_order(BtNode *ptr)
{
stack<BtNode *> st;
st.push (ptr);
BtNode *pre=NULL;
while(!st.empty())
{
ptr=st.top();
//如果当前节点没有左右孩子,或者有左孩子或有孩子,但已经被访问输出,
//则直接输出该节点,将其出栈,将其设为上一个访问的节点
if((ptr->leftchild==NULL && ptr->rightchild==NULL)
||( pre && (ptr->leftchild==pre || ptr->rightchild==pre)))
{
printf("%c ",ptr->data);
pre=ptr;//让pre记录Ptr之前访问的结点
st.pop();
}
else
{
if(ptr->rightchild!=NULL)
{
st.push (ptr->rightchild);
}
if(ptr->leftchild!=NULL)
{
st.push (ptr->leftchild);
}
}
}
}
层次遍历(非递归)
//二叉树的层序遍历
//二叉树的层序遍历,由于其层级的关系,需要借助队列实现,从左到右,自上而下
//一次将二叉树的各个结点入队,这样便可以保证输出的顺序是层序排列的
void level_order(BtNode *ptr)
{
queue<BtNode *> qu;
if(ptr==NULL)
{
return;
}
qu.push(ptr);
while(!qu.empty())
{
ptr=qu.front();
printf("%c ",ptr->data);
qu.pop();
if(ptr->leftchild!=NULL)
{
qu.push(ptr->leftchild);
}
if(ptr->rightchild!=NULL)
{
qu.push(ptr->rightchild);
}
}
}