前序中序构造二叉树
前言:前序中序构造二叉树笔记
#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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话