C语言实现二叉树的非递归中序遍历

创建一个栈

注意,这个栈的目的时用来保存结点地址的。因为我们在出栈时,还需判断结点的右节点的情况,如果只是保存结点的值,是无法实现中序遍历的。

现在我们来创建一个栈。首先定义一个栈的结构,不过之前还需定义一个节点结构

节点定义

typedef struct BinaryTreeNode{
	int data;
	struct BinaryTreeNode *lchild, *rchild;//左右孩子指针 
}BinaryTreeNode, *pBinaryTreeNode;

栈结构定义

typedef struct {
	pBinaryTreeNode *stack;//栈的指针,由于入栈的是节点地址,所以必须为二级指针
	int top;//标识栈顶位置
	int stacksize;//标识栈的容量
}MyStack;

栈的操作函数

  1. 栈的初始化函数。
    初始化栈结构的数据成员:确认栈的大小,申请一块栈空间。
void initstack(MyStack *_s,int _stacksize)
{
	//1.初始化栈内部变量
	_s->stacksize = _stacksize; //确认栈的大小
	_s->top = -1; //初始栈顶位置为-1
	//2.申请内存空间
	_s->stack = (pBinaryTreeNode*)malloc(sizeof(pBinaryTreeNode)*(_s->stacksize));
}
  1. 栈的Empty函数
    判断栈是否为空,为空返回1。为空的条件是栈结构中的数据成员top<0
int StackEmpty(MyStack *_s)
{
	if (_s->top < 0) return 1;
	return 0;
}
  1. 栈的Push函数
    传入树节点的地址。注意栈满了是当栈顶top达到栈的大小stacksize。由于top从0开始,所以是top= stacksize-1为栈满
void StackPush(MyStack *_s, pBinaryTreeNode _pdata)
{
	if (_s->top == _s->stacksize - 1)
		//栈满了
		exit(1);
	else{
		_s->stack[++(_s->top)] = _pdata;
	}
}
  1. 栈的Pop函数
    删除栈顶数据。
void StackPop(MyStack *_s)
{
	if (StackEmpty(_s) == 1)
		//栈为空
		exit(1);
	else{
		_s->top--;
	}
}
  1. 栈的Top函数
    返回栈顶数据。
pBinaryTreeNode StackTop(MyStack *_s)
{
	if (StackEmpty(_s) == 1)
		//栈为空
		exit(1);
	else{
		return _s->stack[_s->top];
	}
}

怎样实现非递归中序遍历

从中序遍历的顺序可以看出,先打印的一定是最左节点。所第一步是找到最左节点,找到之后可以立马打印数据。第二步是判断已打印数据的右节点,为空则继续出栈;不空则重复第一步的操作。依次循环这两步,直到栈为空。

int inorder(pBinaryTreeNode root){
	MyStack s;
	initstack(&s, 10);
	pBinaryTreeNode current = root;

	if (current == nullptr) return 0;

	while (current || !StackEmpty(&s)){
		if (current){
			StackPush(&s, current);
			current = current->lchild;
		}
		else{
			current = StackTop(&s);
			StackPop(&s);

			printf("%d",current->data);//打印数据
			current = current->rchild;
		}
	}
	return 1;
}

完整代码和测试结果

完整代码:

#include<stdio.h>
#include<stdlib.h>

//二叉树节点定义 
typedef struct BinaryTreeNode{
	int data;
	struct BinaryTreeNode *lchild, *rchild;//左右孩子指针 
}BinaryTreeNode, *pBinaryTreeNode;

//定义栈
typedef struct {
	pBinaryTreeNode *stack;
	int top;
	int stacksize;
}MyStack;

//初始化栈
void initstack(MyStack *_s,int _stacksize)
{
	//1.初始化栈内部变量
	_s->stacksize = _stacksize;
	_s->top = -1;
	//2.申请内存空间
	_s->stack = (pBinaryTreeNode*)malloc(sizeof(pBinaryTreeNode)*(_s->stacksize));
}

//判断栈是否为空
int StackEmpty(MyStack *_s)
{
	if (_s->top < 0) return 1;
	return 0;
}
//栈的push操作
void StackPush(MyStack *_s, pBinaryTreeNode _pdata)
{
	if (_s->top == _s->stacksize - 1)
		//栈满了
		exit(1);
	else{
		_s->stack[++(_s->top)] = _pdata;
	}
}
//栈的top操作:返回栈顶指针
pBinaryTreeNode StackTop(MyStack *_s)
{
	if (StackEmpty(_s) == 1)
		//栈为空
		exit(1);
	else{
		return _s->stack[_s->top];
	}
}
//栈的pop操作:删除栈顶数据
void StackPop(MyStack *_s)
{
	if (StackEmpty(_s) == 1)
		//栈为空
		exit(1);
	else{
		//free(_s->stack[_s->top]);//释放内存
		_s->top--;
	}
}
//中序遍历
int inorder(pBinaryTreeNode root){
	MyStack s;
	initstack(&s, 10);
	pBinaryTreeNode current = root;

	if (current == nullptr) return 0;

	while (current || !StackEmpty(&s)){
		if (current){
			StackPush(&s, current);
			current = current->lchild;
		}
		else{
			current = StackTop(&s);
			StackPop(&s);

			printf("%d",current->data);//打印数据
			current = current->rchild;
		}
	}
	return 1;
}

//创建二叉树 
pBinaryTreeNode CreatBinaryTree(){
	pBinaryTreeNode node;
	int _data;

	scanf("%d", &_data);

	//确认递归的结束的条件
	if (_data < 0)//由于是用户输入节点,当用户输入9999时,递归结束
		return nullptr;

	node = (pBinaryTreeNode)malloc(sizeof(BinaryTreeNode));
	node->data = _data;

	node->lchild = CreatBinaryTree();//生成左子树 
	node->rchild = CreatBinaryTree();//生成右子树 

	return node;
}

int main(){
	
	printf("请按照先序遍历输入二叉树:\n");

	//方法一:动态的创建一课树
	pBinaryTreeNode rootDyn = nullptr; 
	rootDyn = CreatBinaryTree();

	printf("二叉树创建成功!\n");
	printf("\n中序非递归遍历:\n");
	inorder(rootDyn);

	system("pause");
	return 0;
}

打印结果:
在这里插入图片描述
注意输入二叉树时,每个数据之间有空格,<0表示空节点。节点的输入是按照树的前序遍历顺序。上面输入的二叉树如下图所示。
在这里插入图片描述

有关如何递归法动态创建一颗二叉树,可参考:递归创建二叉树(C版)

本人水平有限,欢迎各位朋友批评指正。

二叉树中序遍历递归实现比较简单,具体步骤如下: 1. 对当前节点的左子树进行中序遍历。 2. 访问当前节点。 3. 对当前节点的右子树进行中序遍历。 下面是该算法的C语言实现代码: ```c #include <stdio.h> #include <stdlib.h> // 结点结构体 typedef struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; } TreeNode; // 二叉树中序遍历递归实现 void inorderTraversal(TreeNode *root) { if (root == NULL) { return; } inorderTraversal(root->left); printf("%d ", root->val); inorderTraversal(root->right); } // 测试 int main() { TreeNode *root = (TreeNode *)malloc(sizeof(TreeNode)); root->val = 1; root->left = (TreeNode *)malloc(sizeof(TreeNode)); root->left->val = 2; root->right = (TreeNode *)malloc(sizeof(TreeNode)); root->right->val = 3; root->left->left = NULL; root->left->right = (TreeNode *)malloc(sizeof(TreeNode)); root->left->right->val = 4; root->left->right->left = (TreeNode *)malloc(sizeof(TreeNode)); root->left->right->left->val = 5; root->left->right->left->left = NULL; root->left->right->left->right = NULL; root->left->right->right = NULL; root->right->left = NULL; root->right->right = (TreeNode *)malloc(sizeof(TreeNode)); root->right->right->val = 6; root->right->right->left = NULL; root->right->right->right = NULL; inorderTraversal(root); printf("\n"); return 0; } ``` 其中,TreeNode是结点的结构体。该算法的时间复杂度为O(n),空间复杂度为O(h),其中h为二叉树的高度。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值