前序中序构造二叉树

前言:前序中序构造二叉树笔记

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 100
#define OK 1
#define ERROR 0

// dim something struct for writting tree's struct;
// travel tree via / pre order travel / in order travel / post order travel
// 代码实现
// 通过中序序列和前序序列来创建对应的二叉树
// 递归算法

typedef int ElemType;
typedef int Status;
// 树相关结点的定义
typedef struct _TreeNode{
	ElemType nodeData;
	struct _TreeNode* pLeftTree;
	struct _TreeNode* pRightTree;
}TreeNode, *PTreeNode;
typedef struct _SqTree{
	TreeNode* pRootTreeNode;
	int iTreeSize;
}SqTree, *PSqTree;

// 链队列用于层次结点遍历
typedef struct _LinkNode{
	TreeNode* pTreeNode;
	struct _LinkNode* nextLinkNode;
}LinkNode, *PLinkNode;
typedef struct _LinkQueue{
	LinkNode* pHeadLinkNode;
}LinkQueue, *PLinkQueue;

// 初始化链队列
Status initLinkQueue(LinkQueue* pLinkQueue)
{
	if (pLinkQueue->pHeadLinkNode != NULL)
		return ERROR;
	// 正常初始化
	pLinkQueue->pHeadLinkNode = malloc(sizeof(LinkNode));
	memset(pLinkQueue->pHeadLinkNode, 0, sizeof(LinkNode));
	return OK;
}

// 队列先进先出
Status push(LinkQueue* pLinkQueue, TreeNode* pTreeNode)
{
	LinkNode* pLinkNode = NULL;
	LinkNode* pTempLinkNode = NULL;
	if (pLinkQueue->pHeadLinkNode == NULL)
		return ERROR;
	pTempLinkNode = pLinkQueue->pHeadLinkNode;
	while (pTempLinkNode->nextLinkNode != NULL)
		pTempLinkNode = pTempLinkNode->nextLinkNode;
	pLinkNode = malloc(sizeof(LinkNode));
	memset(pLinkNode, 0, sizeof(LinkNode));
	pLinkNode->pTreeNode = pTreeNode;
	if (pLinkNode == NULL)
		return ERROR;
	pTempLinkNode->nextLinkNode = pLinkNode;
	return OK;
}

LinkNode* pop(LinkQueue* pLinkQueue)
{
	LinkNode* pLinkNode = NULL;
	if (pLinkQueue->pHeadLinkNode == NULL)
		return ERROR;
	pLinkNode = pLinkQueue->pHeadLinkNode->nextLinkNode; // 取出当前头节点之后的一个pLinkNode结点
	pLinkQueue->pHeadLinkNode->nextLinkNode = pLinkQueue->pHeadLinkNode->nextLinkNode->nextLinkNode; // 将当前头结点指向下一个结点的下一个结点
	return pLinkNode;
}

Status checkQueueEmpty(LinkQueue* pLinkQueue)
{
	return pLinkQueue->pHeadLinkNode->nextLinkNode == NULL ? OK : ERROR;
}

// init root tree node
Status initRootTreeNode(SqTree* pSqTree)
{
	if (pSqTree->pRootTreeNode != NULL)
		return ERROR;
	pSqTree->pRootTreeNode = malloc(sizeof(TreeNode));
	memset(pSqTree->pRootTreeNode, 0, sizeof(TreeNode));
	pSqTree->pRootTreeNode->nodeData = 1; //根节点的数据初始化为1
	if (pSqTree->pRootTreeNode != NULL)
		return OK;
	else
		return ERROR;
}

// 层序遍历/层次遍历
Status layerTravel(SqTree* pSqTree)
{
	LinkQueue linkQueue;
	LinkNode* pLinkNode = NULL;
	memset(&linkQueue, 0, sizeof(LinkQueue));
	initLinkQueue(&linkQueue);
	push(&linkQueue, pSqTree->pRootTreeNode);
	while (!checkQueueEmpty(&linkQueue))
	{
		pLinkNode = pop(&linkQueue);
		printf("current get a node -> %d\n", pLinkNode->pTreeNode->nodeData);
		if (pLinkNode->pTreeNode->pLeftTree != NULL)
			push(&linkQueue, pLinkNode->pTreeNode->pLeftTree);
		if (pLinkNode->pTreeNode->pRightTree != NULL)
			push(&linkQueue, pLinkNode->pTreeNode->pRightTree);
	}
	return OK;
}

TreeNode* createTreeFromPreMiddle(char* pPreString, char* pMiddleString)
{
	if (*pPreString == '\0' || *pMiddleString == '\0')
		return NULL;
	char* pChar = pMiddleString;
	char newLeftMiddleString[0x10] = { 0 };
	char newLeftPreString[0x10] = { 0 };
	char newRightMiddleString[0x10] = { 0 };
	char newRightPreString[0x10] = { 0 };
	int iLeftMiddleLength = 0;
	int iLeftPreLength = 0;
	int iRightMiddleLength = 0;
	int iRightPreLength = 0;
	TreeNode* pTreeNode = malloc(sizeof(TreeNode));
	memset(pTreeNode, 0, sizeof(TreeNode));
	pTreeNode->nodeData = pPreString[0];
	while (*pChar != pTreeNode->nodeData) // pTreeNode->nodeData 此时存储的就是根结点的标识符,所以这里可以直接用pTreeNode->nodeData来做验证处理
	{
		iLeftMiddleLength++; // 记录的是中序序列以根节点字符进行分割,左子树序列的长度,这个长度也会作为前序序列的左子树序列的长度
		pChar++;
	}
	// 下面的是左子树相关的前序序列和中序序列
	memcpy(newLeftPreString, pPreString + 1, iLeftMiddleLength);
	memcpy(newLeftMiddleString, pMiddleString, iLeftMiddleLength); // newMiddleString存储的就是下一次用的中序序列
	pTreeNode->pLeftTree = createTreeFromPreMiddle(newLeftPreString, newLeftMiddleString); // 构建当前结点的左子树
	// 下面的长度需要基于上面的长度之后,因为下面的是右子树相关的前序序列和中序序列
	memcpy(newRightPreString, pPreString + 1 + iLeftMiddleLength, strlen(pPreString) - 1 - iLeftMiddleLength);
	memcpy(newRightMiddleString, pMiddleString + 1 + iLeftMiddleLength, strlen(pMiddleString) - 1 - iLeftMiddleLength);
	pTreeNode->pRightTree = createTreeFromPreMiddle(newRightPreString, newRightMiddleString); // 构建当前结点的右子树
	return pTreeNode;
}

int main()
{
	char preBuffer[0x20] = { 0 };
	char middleBuffer[0x20] = { 0 };
	TreeNode* pRootTreeNode = NULL;
	SqTree sqTree;
	printf("preBuffer -> ");
	scanf("%s", &preBuffer);
	printf("middleBuffer -> ");
	scanf("%s", &middleBuffer);
	pRootTreeNode = createTreeFromPreMiddle(preBuffer, middleBuffer);
	sqTree.pRootTreeNode = pRootTreeNode;
	layerTravel(&sqTree);
	return 0;
}

posted @ 2022-04-03 10:06  zpchcbd  阅读(51)  评论(0)    收藏  举报