前序中序构造二叉树

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

#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 @   zpchcbd  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示