数据结构与算法简记:根据广义表构建二叉树
来源:互联网 发布:信用卡怎么淘宝套现 编辑:程序博客网 时间:2024/05/01 22:55
使用广义表(generalized lists)来表示二叉树非常方便,假如我们有这么一个二叉树:
它可以表示为L = (A (B (C, D), E ( , F) ) ),直观地表达了树中各个节点之间的关系。
今天主要记录如何通过解析这个广义表,构建出真实的树存储结构。
下面是其主要思路:
逐个获取广义表字符串中除空格之外的每个字符,遇到左括号就标记START_LEFT_CHILD,遇到逗号就标记START_RIGHT_CHILD,遇到右括号就返回到父节点层次。当遇到字母时,就创建一个节点,并与父节点进行关联。
- 遇到左括号时,下一步就要处理左子节点了,此时将当前新创建的节点入栈作为栈顶元素(第一次为空),它是下一个新创建节点的父节点。
- 遇到字母A时,创建一个节点对象作为根节点;之后再遇到字母时,如果当前标记为START_LEFT_CHILD,就作为父节点的左子节点,如果当前标记为START_RIGHT_CHILD,那就作为父节点的右子节点。
- 遇到右括号时,返回父节点层次,此时相应元素出栈,栈顶指针退回一位。
- 继续重复上几个步骤,最终返回根节点。
构建完二叉树后,我们会获取到根节点,然后就可以对二叉树进行各种遍历,来验证其正确性。
下面是实现代码:
JS版:
//二叉树节点结构function BinTreeNode(data) { this.data = data; this.leftChild = null; this.rightChild = null;}//通过广义表创建二叉树function createBinTreeByGLists(gLists) { //根节点和当前节点 var rootNode = null, currNode = null; //数组作为栈结构,top为栈顶指针,模拟入栈出栈 var stack = [], top = -1; //flag标识当前要解析的类型 var flag = 0; var START_LEFT_CHILD = 1, START_RIGHT_CHILD = 2; //字符串当前索引 var index = 0; while (index < gLists.length) { //获取广义表字符串当前要解析的字符 var c = gLists.charAt(index++); switch(c) { //遇到'('时,开始解析左子节点,栈顶指针递增一位,当前节点入栈作为新的父节点 case '(': flag = START_LEFT_CHILD; stack[++top] = currNode; break; //遇到',' 开始解析右子节点 case ',': flag = START_RIGHT_CHILD; break; //遇到')'时,栈顶指针递减一位,返回到父节点层次 case ')': top--; break; //忽略空格 case ' ': break; //处理节点 default: //创建新节点 currNode = new BinTreeNode(c); //第一个节点作为根节点 if (rootNode === null) { rootNode = currNode; } else { //当前栈顶存放父节点,根据flag处理与父节点的关系 switch(flag) { case START_LEFT_CHILD: stack[top].leftChild = currNode; break; case START_RIGHT_CHILD: stack[top].rightChild = currNode; break; } } } } //返回树的根节点 return rootNode;}//前序遍历function preOrderTraverse(node, orderArray) { if (node) { orderArray.push(node.data); preOrderTraverse(node.leftChild, orderArray); preOrderTraverse(node.rightChild, orderArray); }}//中序遍历function inOrderTraverse(node, orderArray) { if (node) { inOrderTraverse(node.leftChild, orderArray); orderArray.push(node.data); inOrderTraverse(node.rightChild, orderArray); }}//后序遍历function postOrderTraverse(node, orderArray) { if (node) { postOrderTraverse(node.leftChild, orderArray); postOrderTraverse(node.rightChild, orderArray); orderArray.push(node.data); }}//广义表序列var gLists = '(A (B (C, D), E ( , F)) )';//根据广义表创建二叉树var binTree = createBinTreeByGLists(gLists);//用于存放节点遍历序列var orderArray = [];preOrderTraverse(binTree, orderArray);console.log(orderArray.join(' '));//清空遍历序列数组orderArray.length = 0;inOrderTraverse(binTree, orderArray);console.log(orderArray.join(' '));orderArray.length = 0;postOrderTraverse(binTree, orderArray);console.log(orderArray.join(' '));
Java版:
//BinTreeNode.javapackage algorithm;//二叉树节点结构public class BinTreeNode { private char data; private BinTreeNode leftChild; private BinTreeNode rightChild; public BinTreeNode(char data) { this.data = data; } public char getData() { return data; } public void setData(char data) { this.data = data; } public BinTreeNode getLeftChild() { return leftChild; } public void setLeftChild(BinTreeNode leftChild) { this.leftChild = leftChild; } public BinTreeNode getRightChild() { return rightChild; } public void setRightChild(BinTreeNode rightChild) { this.rightChild = rightChild; }}//BinTreeCreator.javapackage algorithm;public class BinTreeCreator { //根据广义表创建二叉树 public static BinTreeNode createBinTreeByGLists(String gLists, int nodeQuantity) { BinTreeNode rootNode = null; BinTreeNode currNode = null; BinTreeNode[] stack = new BinTreeNode[nodeQuantity]; int top = -1; int flag = 0; final int START_LEFT_CHILD = 1, START_RIGHT_CHILD = 2; int index = 0; while (index < gLists.length()) { char c = gLists.charAt(index++); switch (c) { case '(': flag = START_LEFT_CHILD; stack[++top] = currNode; break; case ',': flag = START_RIGHT_CHILD; break; case ')': top--; break; case ' ': break; default: currNode = new BinTreeNode(c); if (rootNode == null) { rootNode = currNode; } else { switch (flag) { case START_LEFT_CHILD: stack[top].setLeftChild(currNode); break; case START_RIGHT_CHILD: stack[top].setRightChild(currNode); break; } } } } return rootNode; } //前序遍历 public static void preOrderTraverse(BinTreeNode node) { if (node != null) { System.out.print(node.getData()); preOrderTraverse(node.getLeftChild()); preOrderTraverse(node.getRightChild()); } } //中序遍历 public static void inOrderTraverse(BinTreeNode node) { if (node != null) { inOrderTraverse(node.getLeftChild()); System.out.print(node.getData()); inOrderTraverse(node.getRightChild()); } } //后序遍历 public static void postOrderTraverse(BinTreeNode node) { if (node != null) { postOrderTraverse(node.getLeftChild()); postOrderTraverse(node.getRightChild()); System.out.print(node.getData()); } } public static void main(String[] args) { String gLists = "(A (B (C, D), E ( , F)) )"; BinTreeNode rootNode = BinTreeCreator.createBinTreeByGLists(gLists, 6); System.out.print("pre order: "); BinTreeCreator.preOrderTraverse(rootNode); System.out.print(System.lineSeparator() + "in order: "); BinTreeCreator.inOrderTraverse(rootNode); System.out.print(System.lineSeparator() + "post order: "); BinTreeCreator.postOrderTraverse(rootNode); }}
C语言版:
#include <stdio.h>#include <stdlib.h>typedef struct node { char data; struct node *lchild, *rchild;} BinTreeNode;BinTreeNode * createBinTreeByGLists(char *gLists, int nodeQuantity);void preOrderTraverse(BinTreeNode *node);void inOrderTraverse(BinTreeNode *node);void postOrderTraverse(BinTreeNode *node);int main(int argc, const char * argv[]) { char *gLists = "(A (B (C, D), E ( , F)) )"; BinTreeNode *rootNode = createBinTreeByGLists(gLists, 6); printf("pre order: "); preOrderTraverse(rootNode); printf("\nin order: "); inOrderTraverse(rootNode); printf("\npost order: "); postOrderTraverse(rootNode); return 0;}//根据广义表创建二叉树BinTreeNode * createBinTreeByGLists(char *gLists, int nodeQuantity) { BinTreeNode *rootNode = NULL; BinTreeNode *currNode = NULL; //创建指针数组作为栈结构 BinTreeNode **stack = (BinTreeNode **) malloc(sizeof(BinTreeNode *) * nodeQuantity); int top = -1; int flag = 0; const int START_LEFT_CHILD = 1, START_RIGHT_CHILD = 2; int index = 0; char c = gLists[index]; while (c != '\0') { switch (c) { case '(': stack[++top] = currNode; flag = START_LEFT_CHILD; break; case ',': flag = START_RIGHT_CHILD; break; case ')': top--; break; case ' ': break; default: currNode = (BinTreeNode *) malloc(sizeof(BinTreeNode)); currNode->data = c; currNode->lchild = currNode->rchild = NULL; if (rootNode == NULL) { rootNode = currNode; } else { switch (flag) { case START_LEFT_CHILD: stack[top]->lchild = currNode; break; case START_RIGHT_CHILD: stack[top]->rchild = currNode; break; } } } c = gLists[++index]; } //释放 free(stack); return rootNode;}//前序遍历void preOrderTraverse(BinTreeNode *node) { if (node != NULL) { printf("%c", node->data); preOrderTraverse(node->lchild); preOrderTraverse(node->rchild); }}//中序遍历void inOrderTraverse(BinTreeNode *node) { if (node != NULL) { inOrderTraverse(node->lchild); printf("%c", node->data); inOrderTraverse(node->rchild); }}//后序遍历void postOrderTraverse(BinTreeNode *node) { if (node != NULL) { postOrderTraverse(node->lchild); postOrderTraverse(node->rchild); printf("%c", node->data); }}
2 0
- 数据结构与算法简记:根据广义表构建二叉树
- 数据结构与算法简记:根据层次顺序存储结构构建二叉树
- 数据结构与算法简记:根据层次顺序存储结构构建二叉树---改进版
- 根据广义表构建二叉树
- 【数据结构与算法】根据遍历结果构建二叉树
- 数据结构与算法简记:通过前序中序或中序后序构建二叉树
- 数据结构与算法简记:非递归遍历二叉树
- 数据结构与算法简记:线索化二叉树
- 数据结构与算法简记:二叉查找树相关操作
- 数据结构与算法简记:线索化二叉树
- 数据结构与算法 简记
- 数据结构与算法简记:AVL树
- 数据结构与算法简记:AVL树
- 数据结构与算法简记:按层次顺序遍历和存储二叉树
- 数据结构之广义表和二叉树
- 算法与数据结构之广义表
- 数据结构与算法简记:红黑树
- 广义的数据结构与算法
- 整行排序时Vlookup 优于 Index Match
- matlab2015b 在 ubuntu16.04中启动崩溃的问题(on startup crash)
- 超越之MongDB系列教程(九)MongDB的java驱动与Spring的整合
- android四大组件之一内容提供者contentprovider
- 图算法—Problem J
- 数据结构与算法简记:根据广义表构建二叉树
- chrome里打开IE?网页里启动本地应用程序?
- golang init和main函数
- HDU 1171 Big Event in HDU
- TI-CCxx系列电磁波唤醒学习笔记
- 【自制】前端html代码格式化小工具
- GitHub上Top20个 Python 语言机器学习项目
- Eclipse将引用了第三方jar包的Java项目打包成jar文件的两种方法
- 找资源网站