1.非递归前序遍历步骤:
1.申请一个辅助栈
2.循环遍历二叉树:如果二叉树结点非空,则打印,结点入栈,二叉树向左走
3. 栈顶元素弹出
4.判断弹出得栈顶元素的右子树:如果右子树存在,则继续重复步骤2,3,4
如果右子树不存在,重复步骤2,3,4
循环直到栈为空时结束
代码如下:
typedef struct node1
{
int nValue;
struct node1 *pLeft;
struct node1 *pRight;
}BinaryTree;
typedef struct node
{
BinaryTree* nValue;
struct node *pNext;
}MyStack;
typedef struct node2
{
MyStack *pTop;
int nCount;
}Stack;
//用到栈的基本操作
void s_Init(Stack **pStack)
{
*pStack = (Stack *)malloc(sizeof(Stack));
(*pStack)->pTop = NULL;
(*pStack)->nCount = 0;
}
void s_Push(Stack *pStack,BinaryTree* nNum)
{
if(pStack == NULL)
{
printf("stack is not exist.\n");
return;
}
MyStack *pTemp = NULL;
pTemp = (MyStack*)malloc(sizeof(MyStack));
pTemp->nValue = nNum;
//新来节点的下一个是原来的栈顶
pTemp->pNext = pStack->pTop;
//新来节点成为新的栈顶
pStack->pTop = pTemp;
//计数器
pStack->nCount++;
}
BinaryTree* s_Pop(Stack *pStack)
{
if(pStack == NULL || pStack->pTop == NULL)return NULL;
MyStack *pDel = NULL;
pDel = pStack->pTop;
BinaryTree* nNum = NULL;
nNum = pDel->nValue;
//原来栈顶的下一个成为新的栈顶
pStack->pTop = pStack->pTop->pNext;
free(pDel);
pDel = NULL;
pStack->nCount--;
return nNum;
}
void UnRecPreTraversal(BinaryTree *pTree)
{
if(pTree == NULL)return;
//申请辅助栈
Stack *pStack = NULL;
s_Init(&pStack);
while(1)
{
while(pTree)
{
//打印
printf("%d ",pTree->nValue);
//入栈
s_Push(pStack,pTree);
//向左走
pTree = pTree->pLeft;
}
//弹出
pTree = s_Pop(pStack);
//结束条件
if(pTree == NULL)break;
//向右走
pTree = pTree->pRight;
}
}
树的中序非递归遍历步骤:
1.申请一个辅助栈
2.循环遍历二叉树:如果二叉树结点非空,则结点入栈,二叉树向左走
3. 栈顶元素弹出,后打印栈顶元素
4.判断弹出得栈顶元素的右子树:如果右子树存在,则继续重复步骤2,3,4
如果右子树不存在,重复步骤2,3,4
循环直到栈为空时结束
中序遍历就是把前序遍历的打印移到栈顶元素弹出后
代码如下:
//栈的基本操作
void s_Init(Stack **pStack)
{
*pStack = (Stack *)malloc(sizeof(Stack));
(*pStack)->pTop = NULL;
(*pStack)->nCount = 0;
}
void s_Push(Stack *pStack,BinaryTree* nNum)
{
if(pStack == NULL)
{
printf("stack is not exist.\n");
return;
}
MyStack *pTemp = NULL;
pTemp = (MyStack*)malloc(sizeof(MyStack));
pTemp->nValue = nNum;
//新来节点的下一个是原来的栈顶
pTemp->pNext = pStack->pTop;
//新来节点成为新的栈顶
pStack->pTop = pTemp;
//计数器
pStack->nCount++;
}
BinaryTree* s_Pop(Stack *pStack)
{
if(pStack == NULL || pStack->pTop == NULL)return NULL;
MyStack *pDel = NULL;
pDel = pStack->pTop;
BinaryTree* nNum = NULL;
nNum = pDel->nValue;
//原来栈顶的下一个成为新的栈顶
pStack->pTop = pStack->pTop->pNext;
free(pDel);
pDel = NULL;
pStack->nCount--;
return nNum;
}
void UnRecInTraversal(BinaryTree *pTree)
{
if(pTree == NULL)return;
//申请辅助栈
Stack *pStack = NULL;
s_Init(&pStack);
while(1)
{
while(pTree)
{
//入栈
s_Push(pStack,pTree);
//向左走
pTree = pTree->pLeft;
}
//弹出
pTree = s_Pop(pStack);
//结束条件
if(pTree == NULL)break;
//注意要在结束条件之后判断,如果在结束条件之前输出,如果pTree已经为空了,在Linux下就会出现段错误
//打印
printf("%d ",pTree->nValue);
//向右走
pTree = pTree->pRight;
}
}
树的后续遍历非递归步骤:
1.申请一个辅助栈
2.循环遍历树的结点,如果结点非空,结点入栈,树等于树的左孩子
3.判断栈顶元素:
栈顶元素有右子树,且右子树被标记过,或者无右子树,则弹出栈顶元素,并打印,标记
栈顶元素有右子树,且没有被标记过,则重复2,3 步
循环直到栈为空时结束
代码如下:
栈的基本操作
void s_Init(Stack **pStack)
{
*pStack = (Stack *)malloc(sizeof(Stack));
(*pStack)->pTop = NULL;
(*pStack)->nCount = 0;
}
void s_Push(Stack *pStack,BinaryTree* nNum)
{
if(pStack == NULL)
{
printf("stack is not exist.\n");
return;
}
MyStack *pTemp = NULL;
pTemp = (MyStack*)malloc(sizeof(MyStack));
pTemp->nValue = nNum;
//新来节点的下一个是原来的栈顶
pTemp->pNext = pStack->pTop;
//新来节点成为新的栈顶
pStack->pTop = pTemp;
//计数器
pStack->nCount++;
}
BinaryTree* s_Pop(Stack *pStack)
{
if(pStack == NULL || pStack->pTop == NULL)return NULL;
MyStack *pDel = NULL;
pDel = pStack->pTop;
BinaryTree* nNum = NULL;
nNum = pDel->nValue;
//原来栈顶的下一个成为新的栈顶
pStack->pTop = pStack->pTop->pNext;
free(pDel);
pDel = NULL;
pStack->nCount--;
return nNum;
}
void UnRecLastTraversal(BinaryTree *pTree)
{
if(pTree == NULL)return;
//申请辅助栈
Stack *pStack = NULL;
s_Init(&pStack);
BinaryTree *pMark = NULL;
while(1)
{
while(pTree)
{
//入栈
s_Push(pStack,pTree);
//向左走
pTree = pTree->pLeft;
}
if(pStack->pTop == NULL)break;
//栈顶元素无右 或者有右且被标记过
if(pStack->pTop->nValue->pRight == NULL || pStack->pTop->nValue->pRight == pMark)
{
//弹出 打印 标记
pMark = s_Pop(pStack);
printf("%d ",pMark->nValue);
}
//有右 且 未被标记
else
{
pTree = pStack->pTop->nValue->pRight;
}
}
}
图解:
无奈没有详细的图解(*^▽^*)