详解用栈实现中序遍历--非递归方法(C++)

详解用栈实现中序遍历–非递归方法(C++)

在考研中考察的几率不大。如果大题考察这个问题难度会很大;小题考察这个问题分值有可能会很高

非递归执行效率高

在这个实现过程中需要使用栈的数据结构点击查看栈相关笔记。

(1) 原理步骤

  1. 构建一个栈 S ,用来接收树的结点。前提是已经层序建好了一棵树

详解用栈实现中序遍历--非递归方法(C++)_第1张图片

  1. 每次遍历之前都要从树根开始,用一个新的变量 p 来接收树根的地址(后续会接收其他树结点的地址)。判断p存在或者栈s不为空即可继续。此时栈为空,但是树根存在所以p就存在,所以继续。

详解用栈实现中序遍历--非递归方法(C++)_第2张图片

  1. 如果P存在,就将p压入栈s中,然后p指向自己的左孩子。

详解用栈实现中序遍历--非递归方法(C++)_第3张图片

  1. 重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P既存在、栈S又不为空,继续。因为P存在,所以将P压入栈S中,然后P指向自己的左孩子

详解用栈实现中序遍历--非递归方法(C++)_第4张图片

  1. 重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P既存在、栈S又不为空,继续。因为P存在,所以将P压入栈S中,然后P指向自己的左孩子

详解用栈实现中序遍历--非递归方法(C++)_第5张图片

  1. 重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P不存在,但是栈S不为空,继续。

    因为这里p不存在,执行的操作是:栈S执行出栈操作(这里可以加上控制台输出操作),并且将出栈元素赋值给p

详解用栈实现中序遍历--非递归方法(C++)_第6张图片

  1. p指向自己的右孩子。

详解用栈实现中序遍历--非递归方法(C++)_第7张图片

  1. 重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P不存在,但是栈S不为空,继续。

    因为这里p不存在,执行的操作是:栈S执行出栈操作(这里可以加上控制台输出操作),并且将出栈元素赋值给p

详解用栈实现中序遍历--非递归方法(C++)_第8张图片

  1. p指向自己的右孩子。

详解用栈实现中序遍历--非递归方法(C++)_第9张图片

  1. 重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P既存在、栈S又不为空,继续。因为P存在,所以将P压入栈S中,然后P指向自己的左孩子

详解用栈实现中序遍历--非递归方法(C++)_第10张图片

  1. 重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P不存在,但是栈S不为空,继续。

    因为这里p不存在,执行的操作是:栈S执行出栈操作(这里可以加上控制台输出操作),并且将出栈元素赋值给p

详解用栈实现中序遍历--非递归方法(C++)_第11张图片

  1. p指向自己的右孩子。

详解用栈实现中序遍历--非递归方法(C++)_第12张图片

  1. 重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P不存在,但是栈S不为空,继续。

    因为这里p不存在,执行的操作是:栈S执行出栈操作(这里可以加上控制台输出操作),并且将出栈元素赋值给p

详解用栈实现中序遍历--非递归方法(C++)_第13张图片

  1. p指向自己的右孩子。

详解用栈实现中序遍历--非递归方法(C++)_第14张图片

  1. 重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,虽然栈S是空的,但是P存在,所以继续。

    因为P存在,所以将P压入栈S中,然后P指向自己的左孩子。

详解用栈实现中序遍历--非递归方法(C++)_第15张图片

  1. 重复上面的操作即可得到最终的队列为:dbeafcg

(2) 代码实现

#include 
using namespace std;

//构建树的结构
typedef char BiElemType;
typedef struct BiTNode
{
	BiElemType data;
	BiTNode* lchild;//树的左孩子结点
	BiTNode* rchild;//树的右孩子结点
}BiTNode,*BiTree;

//栈的相关数据结构
#define MaxSize 50
typedef BiTree ElemType;

typedef struct SqStack {
	ElemType data[MaxSize];
	int top;
};

/*
以下为栈的方法实现
*/
void InitStack(SqStack& S) {
	S.top = -1;
}

bool Push(SqStack& S, ElemType e) {
	if (S.top == MaxSize - 1) {
		return false;
	}
	S.top++;
	S.data[S.top] = e;
	return true;
}

bool Pop(SqStack& S, ElemType& x) {
	if (S.top == -1) {
		return false;
	}
	x = S.data[S.top];
	S.top--;
	return true;
}

bool GetTop(SqStack S, ElemType& x) {
	if (S.top == -1)
	{
		return false;
	}
	x = S.data[S.top];
	return true;
}
bool StackEmpty(SqStack S) {
	if (S.top == -1) {
		return true;
	}
	return false;
}

//中序遍历非递归
void InOrder2(BiTree T) {//传入的参数是树根的地址
	SqStack S;
	InitStack(S);
	BiTree p = T;//用一个遍历的变量p,先等于树根
	while (p || !StackEmpty(S)) {
		if (p) {
			//不断压栈的过程找到了最左边的左孩子
			Push(S, p);
			p = p->lchild;
		}
		else
		{
			Pop(S, p);
			putchar(p->data);
			p = p->rchild;
		}
	}
}

详解用栈实现中序遍历--非递归方法(C++)_第16张图片

你可能感兴趣的:(C++数据结构笔记,数据结构,c++,算法)