二叉树前,中,后序遍历

-前言

树是一种常用的数据结构,用来模拟具有树状结构性质的数据集合。树里的每一个节点(结构体)有一个值和一个包含所有子节点的列表。二叉树则是更典型的树结构,每个结点最多有两个子节点。接下来记录二叉树的三种遍历方法。

-中序遍历

什么是二叉树的中序遍历:按照访问左子树——根节点——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。这里先讲中序排序,是因为中序排序与后序排序的迭代法思路较为类似,相对好理解一点,而前序遍历比较不同,放在最后说。

- 以上图这个树来说,中序遍历的结果应该是DBEAFCG-

递归法

树的遍历思路显然可以用递归来实现。递归的出口为结点空,先记录当前节点的数据,再先遍历root->left后遍历root->right即可。递归较容易理解

void inorder(struct TreeNode* root, int* res, int* returnSize){
	if(root == NULL){
		return;
	}
	inorder(root->left, res, returnSize);
	res[(*returnSize)++] = root->val;
	inorder(root->right, res, returnSize);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize){
	int* res = (int*)malloc(sizeof(int) * 2000);
	*returnSize = 0;
	inorder(root, res, returnSize);
	return res;
}

迭代法

迭代法与递归的原理很相似,都是用了栈的思想(入栈出栈),递归的栈是暗含的,迭代就是直接使用一个栈帮助遍历。迭代法个人感觉较难理解,学习的时候最好能自己动手在纸上模拟一下过程。

int* inorderTraversal(struct TreeNode* root, int* returnSize){
	int* res = (int*)malloc(sizeof(int) * 2000);
	*returnSize = 0;
	if(root == NULL){
		return res;
	}
	struct TreeNode** Node = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 501);
	//struct TreeNode* Node[500];
	int top;
	while(root != NULL || top != 0){
		while(root != NULL){
			Node[top++] = root;
			root = root->left;
		}
		root = Node[--top];
		res[(*returnSize)++] = root->val;
		root = root->right;
	}
	return res;
}

​

-后序遍历

什么是二叉树的后序遍历:按照访问左子树——右子树——根节点的方式遍历这棵树。

- 以上​​​​​​​图这个树来说,后序遍历的结果应该是DEBFGCA-

递归法

递归法大部分代码与中序相同,唯一不同的在于递归函数里记录数据的先后顺序

    postorder(root->left, res, returnSize);
	postorder(root->right, res, returnSize);
	res[(*returnSize)++] = root->val;

迭代法

后序遍历的迭代法与中序的迭代法思路大致相同,不同在于出栈之后要考虑右子树是否为空,不为空的话需要把出栈的数值再入栈,不记录数据,且从右子树开始继续遍历直到遇到右子树为空停止。设置prev结点的用途是在开始记录右子树的数据时标记记录过的结点,帮助后续出栈的进行

int* postorderTraversal(struct TreeNode* root, int* returnSize){
	int* res = (int*)malloc(sizeof(int) * 2000);
	*returnSize = 0;
	if(root == NULL){
		return res;
	}
	struct TreeNode* Node[500];
	struct TreeNode* prev = NULL;
	int top = 0;
	while(root != NULL || top != 0){
		while(root != NULL){
			Node[top++] = root;
			root = root->left;
		}
		root = Node[--top];
		if(root->right == NULL || root->right == prev){
			res[(*returnSize)++] = root->val;
			prev = root;
			root = NULL;
		}
		else{
			Node[top++] = root;
			root = root->right;
		}
	}
	return res;
}

-前序遍历

什么是二叉树的前序遍历:按照访问根节点——左子树——右子树的方式遍历这棵树。

- 以上​​​​​​​图这个树来说,前序遍历的结果应该是ABDECFG-

递归法

代码大部分与中序相同,不同之处在于:

    res[(*returnSize)++] = root->val;
	preorder(root->left, res, returnSize);
	preorder(root->right, res, returnSize);

迭代法

前序排序的迭代法不同在于入栈时就存储数据,具体代码如下。

int* preorderTraversal(struct TreeNode* root, int* returnSize){
	int* res = (int*)malloc(sizeof(int) * 2000);
	*returnSize = 0;
	if(root == NULL){
		return res;
	}
	struct TreeNode* Node[500];
	int top = 0;
	while(root != NULL || top != 0){
		while(root != NULL){
			res[(*returnSize)++] = root->val;
			Node[top++] = root;
			root = root->left;
		}
		root = Node[--top];
		root = root->right;
	}
	retuen res;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值