【数据结构】基于栈的二叉树先/中/后序非递归遍历(C语言)

二叉树的递归遍历:https://blog.csdn.net/weixin_51450101/article/details/122742243?spm=1001.2014.3001.5501

1. 直接实现栈操作方法

1.1 先序遍历

/*先序遍历二叉树的非递归算法(直接实现栈操作)*/
void PreOrder(BiTree bt) {
    
    
//s[m]表示栈,top表示栈顶指针
	BiTNode* s[Stack_Size];
	int top = 0;
	BiTNode* p = bt;
	do {
    
    
		while (p != NULL) {
    
    
			if (top > Stack_Size)
				return;
			printf("%c ", p->data);
			top = top + 1;
			s[top] = p;
			p = p->LChild;
		}
		if (top != 0) {
    
    
			p = s[top];
			top = top - 1;
			p = p->RChild;
		}
	} while (p != NULL || top != 0);
}

1.2 中序遍历

/*中序遍历二叉树的非递归算法(直接实现栈操作)*/
void InOrder(BiTree bt) {
    
    
//s[m]表示栈,top表示栈顶指针
	BiTNode* s[Stack_Size];
	int top = 0;
	BiTNode* p = bt;
	do {
    
    
		while (p != NULL) {
    
    
			if (top > Stack_Size)
				return;
			top = top + 1;
			s[top] = p;
			p = p->LChild;
		}
		if (top != 0) {
    
    
			p = s[top];
			top = top - 1;
			printf("%c ", p->data);
			p = p->RChild;
		}
	} while (p != NULL || top != 0);
}

1.3 后序遍历

/*后序遍历二叉树的非递归算法(直接实现栈操作)*/
void PostOrder(BiTree bt) {
    
    
//s[m]表示栈,top表示栈顶指针
	BiTNode* s[Stack_Size];
	int top = 0;
	BiTNode* p = bt, * q = NULL;
	while (p != NULL || top != 0) {
    
    
		if (p != NULL) {
    
    
			if (top > Stack_Size)
				return;
			top = top + 1;
			s[top] = p;
			p = p->LChild;
		}
		else {
    
    
			p = s[top];
			if (p->RChild == NULL || p->RChild == q) {
    
    //无右孩子结点或右孩子结点已遍历过
				printf("%c ", p->data);
				q = p;
				top = top - 1;
				p = NULL;
			}
			else
				p = p->RChild;
		}
	}
}

1.4 完整实现代码

# include<stdio.h>
# include<malloc.h>
# define Stack_Size 50

/*二叉树的链式存储结构*/
typedef char DataType;
typedef struct Node {
    
    
	DataType data;
	struct Node* LChild;
	struct Node* RChild;
}BiTNode, * BiTree;

/*按扩展先序遍历序列创建二叉树*/
void CreateBiTree(BiTree* bt) {
    
    
	char ch;
	ch = getchar();
	if (ch == '.')
		*bt = NULL;
	else {
    
    
		*bt = (BiTree)malloc(sizeof(BiTNode));
		(*bt)->data = ch;
		CreateBiTree(&((*bt)->LChild));
		CreateBiTree(&((*bt)->RChild));
	}
}

/*先序遍历二叉树的非递归算法(直接实现栈操作)*/
void PreOrder(BiTree bt) {
    
    
//s[m]表示栈,top表示栈顶指针
	BiTNode* s[Stack_Size];
	int top = 0;
	BiTNode* p = bt;
	do {
    
    
		while (p != NULL) {
    
    
			if (top > Stack_Size)
				return;
			printf("%c ", p->data);
			top = top + 1;
			s[top] = p;
			p = p->LChild;
		}
		if (top != 0) {
    
    
			p = s[top];
			top = top - 1;
			p = p->RChild;
		}
	} while (p != NULL || top != 0);
}

/*中序遍历二叉树的非递归算法(直接实现栈操作)*/
void InOrder(BiTree bt) {
    
    
//s[m]表示栈,top表示栈顶指针
	BiTNode* s[Stack_Size];
	int top = 0;
	BiTNode* p = bt;
	do {
    
    
		while (p != NULL) {
    
    
			if (top > Stack_Size)
				return;
			top = top + 1;
			s[top] = p;
			p = p->LChild;
		}
		if (top != 0) {
    
    
			p = s[top];
			top = top - 1;
			printf("%c ", p->data);
			p = p->RChild;
		}
	} while (p != NULL || top != 0);
}

/*后序遍历二叉树的非递归算法(直接实现栈操作)*/
void PostOrder(BiTree bt) {
    
    
//s[m]表示栈,top表示栈顶指针
	BiTNode* s[Stack_Size];
	int top = 0;
	BiTNode* p = bt, * q = NULL;
	while (p != NULL || top != 0) {
    
    
		if (p != NULL) {
    
    
			if (top > Stack_Size)
				return;
			top = top + 1;
			s[top] = p;
			p = p->LChild;
		}
		else {
    
    
			p = s[top];
			if (p->RChild == NULL || p->RChild == q) {
    
    //无右孩子结点或右孩子结点已遍历过
				printf("%c ", p->data);
				q = p;
				top = top - 1;
				p = NULL;
			}
			else
				p = p->RChild;
		}
	}
}

int main() {
    
    
	BiTree bt;
	printf("树的创建:");
	CreateBiTree(&bt);
	printf("先序遍历:");
	PreOrder(bt);
	printf("\n中序遍历:");
	InOrder(bt);
	printf("\n后序遍历:");
	PostOrder(bt);
	return 0;
}

1.5 运行结果

运行结果运行用例对应的树
运行用例对应的树

2. 调用栈操作的函数方法

2.1 先序遍历

/*基于栈的二叉树先序遍历(调用栈操作函数)*/
void PreOrder(BiTree bt) {
    
    
	InitStack(&S);
	BiTNode* p = bt;
	while (p != NULL || !IsEmpty(S)) {
    
    
		if (p != NULL) {
    
    
			printf("%c ", p->data);
			Push(&S, p);				//入栈操作
			p = p->LChild;
		}
		else {
    
    
			p = S.elem[S.top];
			Pop(&S);					//出栈操作
			p = p->RChild;
		}
	}
}

2.2 中序遍历

/*基于栈的二叉树中序遍历(调用栈操作函数)*/
void InOrder(BiTree bt) {
    
    
	InitStack(&S);
	BiTNode* p = bt;
	while (p != NULL || !IsEmpty(S)) {
    
    
		if (p != NULL) {
    
    
			Push(&S, p);				//入栈操作
			p = p->LChild;
		}
		else {
    
    
			p = S.elem[S.top];
			Pop(&S);					//出栈操作	
			printf("%c ", p->data);
			p = p->RChild;
		}
	}
}

2.3 后序遍历

/*基于栈的二叉树后序遍历(调用栈操作函数)*/
void PostOrder(BiTree bt) {
    
    
	BiTNode* p, * q;
	q = NULL;
	p = bt;
	InitStack(&S);
	while (p != NULL || !IsEmpty(S)) {
    
    
		if (p != NULL) {
    
    
			Push(&S, p);				//入栈操作
			p = p->LChild;
		}
		else {
    
    
			p = S.elem[S.top];
			if (p->RChild == NULL || p->RChild == q) {
    
    //无右孩子结点或右孩子结点已遍历过
				printf("%c ", p->data);
				q = p;
				Pop(&S);				//出栈操作
				p = NULL;
			}
			else
				p = p->RChild;
		}
	}
}

2.4 完整实现代码

# include<stdio.h>
# include<malloc.h>
# define Stack_Size 50
# define TRUE 1
# define FALSE 0

/*二叉树的链式存储结构*/
typedef char DataType;
typedef struct Node {
    
    
	DataType data;
	struct Node* LChild;
	struct Node* RChild;
}BiTNode, * BiTree;

/*按扩展先序遍历序列创建二叉树*/
void CreateBiTree(BiTree* bt) {
    
    
//‘.’表示空子树
	char ch;
	ch = getchar();
	if (ch == '.')
		*bt = NULL;
	else {
    
    
		*bt = (BiTree)malloc(sizeof(BiTNode));
		(*bt)->data = ch;
		CreateBiTree(&((*bt)->LChild));
		CreateBiTree(&((*bt)->RChild));
	}
}

/*顺序栈的存储结构*/
typedef struct {
    
    
	BiTNode* elem[Stack_Size];
	int top;
}SeqStack;

SeqStack S;

/*初始化顺序栈*/
void InitStack(SeqStack* S) {
    
    
	S->top = -1;
}

/*顺序栈进栈*/
int Push(SeqStack* S, BiTNode* x) {
    
    
	if (S->top == Stack_Size - 1)
		return FALSE;
	S->top++;
	S->elem[S->top] = x;
	return TRUE;
}

/*顺序栈出栈*/
int Pop(SeqStack* S) {
    
    
	if (S->top == -1)
		return FALSE;
	else
		S->top--;
	return TRUE;
}

/*顺序栈判空函数*/
int IsEmpty(SeqStack S) {
    
    
	if (S.top == -1)
		return TRUE;
	else
		return FALSE;
}

/*基于栈的二叉树先序遍历(调用栈操作函数)*/
void PreOrder(BiTree bt) {
    
    
	InitStack(&S);
	BiTNode* p = bt;
	while (p != NULL || !IsEmpty(S)) {
    
    
		if (p != NULL) {
    
    
			printf("%c ", p->data);
			Push(&S, p);
			p = p->LChild;
		}
		else {
    
    
			p = S.elem[S.top];
			Pop(&S);
			p = p->RChild;
		}
	}
}

/*基于栈的二叉树中序遍历(调用栈操作函数)*/
void InOrder(BiTree bt) {
    
    
	InitStack(&S);
	BiTNode* p = bt;
	while (p != NULL || !IsEmpty(S)) {
    
    
		if (p != NULL) {
    
    
			Push(&S, p);
			p = p->LChild;
		}
		else {
    
    
			p = S.elem[S.top];
			Pop(&S);
			printf("%c ", p->data);
			p = p->RChild;
		}
	}
}

/*基于栈的二叉树后序遍历(调用栈操作函数)*/
void PostOrder(BiTree bt) {
    
    
	BiTNode* p, * q;
	q = NULL;
	p = bt;
	InitStack(&S);
	while (p != NULL || !IsEmpty(S)) {
    
    
		if (p != NULL) {
    
    
			Push(&S, p);
			p = p->LChild;
		}
		else {
    
    
			p = S.elem[S.top];
			if (p->RChild == NULL || p->RChild == q) {
    
    //无右孩子结点或右孩子结点已遍历过
				printf("%c ", p->data);
				q = p;
				Pop(&S);
				p = NULL;
			}
			else
				p = p->RChild;
		}
	}
}

int main() {
    
    
	BiTree bt;
	printf("树的创建:");
	CreateBiTree(&bt);
	printf("先序遍历:");
	PreOrder(bt);
	printf("\n中序遍历:");
	InOrder(bt);
	printf("\n后序遍历:");
	PostOrder(bt);
	return 0;
}

2.5 运行结果

运行结果运行用例所对应的树
运行用例所对应的树
参考:耿国华《数据结构——用C语言描述(第二版)》

更多数据结构内容关注我的《数据结构》专栏https://blog.csdn.net/weixin_51450101/category_11514538.html?spm=1001.2014.3001.5482

猜你喜欢

转载自blog.csdn.net/weixin_51450101/article/details/122813037