建立森林,并进行先序和中序遍历(C语言代码实现)

森林先序遍历算法思想:先访问森林中一棵树的根节点,依次对该树的结点(子树的根)进行先根遍历,最后先序遍历森林中其余待访问的树。

森林的中序遍历算法思想:对第一颗树的结点(子树的根)进行后根遍历,然后访问该树的根节点,再对森林中其他树进行中序遍历.

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char ElemType;
typedef struct CSTNode {
	ElemType data;
	struct CSTNode* firstChild;
	struct CSTNode* nextSibling;
}CSTNode,*CSTree;
//先序创建森林(孩子兄弟链)
void creatCSTree(CSTree& T) {
	ElemType ch;
	scanf("%c", &ch);
	if (ch == '#') {
		T = NULL;
	}
	else {
		T = (CSTNode*)malloc(sizeof(CSTNode));
		T->data = ch;
		creatCSTree(T->firstChild);
		creatCSTree(T->nextSibling);
	}
}
//先序遍历二叉树,检验建树是否成功
//void preOrder(CSTree T) {
//	if (T != NULL) {
//		printf("%c", T->data);
//		preOrder(T->firstChild);
//		preOrder(T->nextSibling);
//	}
//}
//树的先根遍历算法
void preOrder(CSTNode* pnode) {
	if (pnode != NULL) {
		printf("%c", pnode->data);//访问根结点
		CSTNode* pcurchild = pnode->firstChild;//获取第一棵子树
		while (pcurchild != NULL) {//依次访问每一棵子树
			preOrder(pcurchild);//先根遍历子树
			pcurchild = pcurchild->nextSibling;//指向T的另一棵子树
		}
	}
}
//先序遍历森林
//算法思想:先访问森林中一棵树的根节点,依次对该树的结点(子树的根)进行先根遍历,最后先序遍历森林中其余待访问的树
void preOrderTraves(CSTree T) {
	if (T != NULL) {
		printf("%c", T->data);//访问第一颗树的根节点
		//依次对该树的结点(子树的根)进行先根遍历
		for (CSTNode* pcurchild = T->firstChild; pcurchild != NULL; pcurchild = pcurchild->nextSibling) {
			preOrder(pcurchild);
		}
		//先序遍历森林中其他的树
		preOrderTraves(T->nextSibling);
	}
}
//树的后跟遍历,先访问每棵子树,最后访问根节点
void postOrder(CSTree T) {
	if (T != NULL) {
		CSTNode* pcurchild = T->firstChild;//获取第一棵子树
		while (pcurchild != NULL) {//依次访问每一棵子树
			postOrder(pcurchild);//后序访问子树
			pcurchild = pcurchild->nextSibling;//访问另一棵子树
		}
		printf("%c", T->data);//访问根节点
	}
}
//森林的中序遍历
//算法思想:对第一颗树的结点(子树的根)进行后根遍历,然后访问该树的根节点,再对森林中其他树进行中序遍历
void inOrderTrave(CSTree T) {
	if (T != NULL) {
		//对第一颗树的结点(子树的根)进行后根遍历
		for (CSTNode* pcurchild = T->firstChild; pcurchild != NULL; pcurchild = pcurchild->nextSibling) {
			postOrder(pcurchild);
		}
		printf("%c", T->data);//访问树的根节点
		inOrderTrave(T->nextSibling);//对森林中其他树进行中序遍历
	}
}
//AB#D#E##C#RS#T###
int main() {
	CSTree T = NULL;
	creatCSTree(T);
	//preOrder(T);//检验建森林是否成功
	//printf("\n");
	preOrderTraves(T);//先序遍历森林
	printf("\n");
	inOrderTrave(T);//中序遍历森林
	printf("\n");
	return 0;
}

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这道题需要用到递归的思想,具体步骤如下: 1. 根据后序遍历找到根节点,即最后一个元素。 2. 在中序遍历中找到根节点的位置,将中序遍历分为左子树和右子树。 3. 根据左子树和右子树的元素个数,将后序遍历也分为左子树和右子树。 4. 递归处理左子树和右子树,直到只剩下一个元素。 5. 输出当前节点的值,即为先序遍历。 下面是c语言代码实现: ```c #include <stdio.h> #include <stdlib.h> typedef struct TreeNode { int val; struct TreeNode* left; struct TreeNode* right; } TreeNode; int findRoot(int* inorder, int inStart, int inEnd, int rootVal) { for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == rootVal) { return i; } } return -1; } TreeNode* buildTree(int* inorder, int inStart, int inEnd, int* postorder, int postStart, int postEnd) { if (inStart > inEnd || postStart > postEnd) { return NULL; } int rootVal = postorder[postEnd]; int rootIndex = findRoot(inorder, inStart, inEnd, rootVal); int leftSize = rootIndex - inStart; TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode)); root->val = rootVal; root->left = buildTree(inorder, inStart, rootIndex - 1, postorder, postStart, postStart + leftSize - 1); root->right = buildTree(inorder, rootIndex + 1, inEnd, postorder, postStart + leftSize, postEnd - 1); return root; } void preorderTraversal(TreeNode* root) { if (root == NULL) { return; } printf("%d ", root->val); preorderTraversal(root->left); preorderTraversal(root->right); } int main() { int inorder[] = { 4, 2, 5, 1, 6, 3 }; int postorder[] = { 4, 5, 2, 6, 3, 1 }; int n = sizeof(inorder) / sizeof(int); TreeNode* root = buildTree(inorder, 0, n - 1, postorder, 0, n - 1); printf("先序遍历结果为:"); preorderTraversal(root); return 0; } ``` 输出结果为:先序遍历结果为:1 2 4 5 3 6

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值