二叉树在C语言中的实现与应用详解

合集下载

数据结构c语言课设-二叉树排序

数据结构c语言课设-二叉树排序

题目:二叉排序树的实现1 内容和要求1)编程实现二叉排序树,包括生成、插入,删除;2)对二叉排序树进展先根、中根、和后根非递归遍历;3)每次对树的修改操作和遍历操作的显示结果都需要在屏幕上用树的形状表示出来。

4)分别用二叉排序树和数组去存储一个班(50 人以上)的成员信息(至少包括学号、姓名、成绩3 项),比照查找效率,并说明在什么情况下二叉排序树效率高,为什么?2 解决方案和关键代码2.1 解决方案:先实现二叉排序树的生成、插入、删除,编写DisplayBST函数把遍历结果用树的形状表示出来。

前中后根遍历需要用到栈的数据构造,分模块编写栈与遍历代码。

要求比照二叉排序树和数组的查找效率,首先建立一个数组存储一个班的成员信息,分别用二叉树和数组查找,利用clock〔〕函数记录查找时间来比照查找效率。

2.2关键代码树的根本构造定义及根本函数typedef struct{KeyType key;} ElemType;typedef struct BiTNode//定义链表{ElemType data;struct BiTNode *lchild, *rchild;}BiTNode, *BiTree, *SElemType;//销毁树int DestroyBiTree(BiTree &T){if (T != NULL)free(T);return 0;}//清空树int ClearBiTree(BiTree &T){if (T != NULL){T->lchild = NULL;T->rchild = NULL;T = NULL;}return 0;}//查找关键字,指针p返回int SearchBST(BiTree T, KeyType key, BiTree f, BiTree &p) {if (!T){p = f;return FALSE;}else if EQ(key, T->data.key){p = T;return TRUE;}else if LT(key, T->data.key)return SearchBST(T->lchild, key, T, p);elsereturn SearchBST(T->rchild, key, T, p);}二叉树的生成、插入,删除生成void CreateBST(BiTree &BT, BiTree p){int i;ElemType k;printf("请输入元素值以创立排序二叉树:\n");scanf_s("%d", &k.key);for (i = 0; k.key != NULL; i++){//判断是否重复if (!SearchBST(BT, k.key, NULL, p)){InsertBST(BT, k);scanf_s("%d", &k.key);}else{printf("输入数据重复!\n");return;}}}插入int InsertBST(BiTree &T, ElemType e){BiTree s, p;if (!SearchBST(T, e.key, NULL, p)){s = (BiTree)malloc(sizeof(BiTNode));s->data = e;s->lchild = s->rchild = NULL;if (!p)T = s;else if LT(e.key, p->data.key)p->lchild = s;elsep->rchild = s;return TRUE;}else return FALSE;}删除//某个节点元素的删除int DeleteEle(BiTree &p){BiTree q, s;if (!p->rchild) //右子树为空{q = p;p = p->lchild;free(q);}else if (!p->lchild) //左子树为空{q = p;p = p->rchild;free(q);}else{q = p;s = p->lchild;while (s->rchild){q = s;s = s->rchild;}p->data = s->data;if (q != p)q->rchild = s->lchild;elseq->lchild = s->lchild;delete s;}return TRUE;}//整棵树的删除int DeleteBST(BiTree &T, KeyType key) //实现二叉排序树的删除操作{if (!T){return FALSE;}else{if (EQ(key, T->data.key)) //是否相等return DeleteEle(T);else if (LT(key, T->data.key)) //是否小于return DeleteBST(T->lchild, key);elsereturn DeleteBST(T->rchild, key);}return 0;}二叉树的前中后根遍历栈的定义typedef struct{SElemType *base;SElemType *top;int stacksize;}SqStack;int InitStack(SqStack &S) //构造空栈{S.base = (SElemType*)malloc(STACK_INIT_SIZE *sizeof(SElemType));if (!S.base) exit(OVERFLOW);S.top = S.base;S.stacksize = STACK_INIT_SIZE;return OK;}//InitStackint Push(SqStack &S, SElemType e) //插入元素e为新栈顶{if (S.top - S.base >= S.stacksize){S.base = (SElemType*)realloc(S.base, (S.stacksize + STACKINCREMENT)*sizeof(SElemType));if (!S.base) exit(OVERFLOW);S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top++ = e;return OK;}//Pushint Pop(SqStack &S, SElemType &e) //删除栈顶,应用e返回其值{if (S.top == S.base) return ERROR;e = *--S.top;return OK;}//Popint StackEmpty(SqStack S) //判断是否为空栈{if (S.base == S.top) return TRUE;return FALSE;}先根遍历int PreOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S;BiTree p;InitStack(S);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);if (!Visit(p->data)) return ERROR;p = p->lchild;}else{Pop(S, p);p = p->rchild;}}return OK;}中根遍历int InOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S;BiTree p;InitStack(S);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);p = p->lchild;}else{Pop(S, p);if (!Visit(p->data)) return ERROR;p = p->rchild;}}return OK;}后根遍历int PostOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S, SS;BiTree p;InitStack(S);InitStack(SS);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);Push(SS, p);p = p->rchild;}else{if (!StackEmpty(S)){Pop(S, p);p = p->lchild;}}}while (!StackEmpty(SS)){Pop(SS, p);if (!Visit(p->data)) return ERROR;}return OK;}利用数组存储一个班学生信息ElemType a[] = { 51, "陈继真", 88,82, "黄景元", 89,53, "贾成", 88,44, "呼颜", 90,25, "鲁修德", 88,56, "须成", 88,47, "孙祥", 87, 38, "柏有患", 89, 9, " 革高", 89, 10, "考鬲", 87, 31, "李燧", 86, 12, "夏祥", 89, 53, "余惠", 84, 4, "鲁芝", 90, 75, "黄丙庆", 88, 16, "李应", 89, 87, "杨志", 86, 18, "李逵", 89, 9, "阮小五", 85, 20, "史进", 88, 21, "秦明", 88, 82, "杨雄", 89, 23, "刘唐", 85, 64, "武松", 88, 25, "李俊", 88, 86, "卢俊义", 88, 27, "华荣", 87, 28, "杨胜", 88, 29, "林冲", 89, 70, "李跃", 85, 31, "蓝虎", 90, 32, "宋禄", 84, 73, "鲁智深", 89, 34, "关斌", 90, 55, "龚成", 87, 36, "黄乌", 87, 57, "孔道灵", 87, 38, "张焕", 84, 59, "李信", 88, 30, "徐山", 83, 41, "秦祥", 85, 42, "葛公", 85, 23, "武衍公", 87, 94, "范斌", 83, 45, "黄乌", 60, 67, "叶景昌", 99, 7, "焦龙", 89, 78, "星姚烨", 85, 49, "孙吉", 90, 60, "陈梦庚", 95,};数组查询函数void ArraySearch(ElemType a[], int key, int length){int i;for (i = 0; i <= length; i++){if (key == a[i].key){cout << "学号:" << a[i].key << " 姓名:" << a[i].name << " 成绩:" << a[i].grade << endl;break;}}}二叉树查询函数上文二叉树根本函数中的SearchBST()即为二叉树查询函数。

二叉树中和为某一值的路径c语言

二叉树中和为某一值的路径c语言

以下是一个使用C语言实现二叉树中和为某一值的路径的示例代码:```c#include <stdio.h>#include <stdlib.h>// 定义二叉树结点结构体struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;};// 中序遍历二叉树,并返回和为target的路径void findPaths(struct TreeNode* root, int target, int sum, struct TreeNode*** paths, int* pathSize) {if (root == NULL) {return;}sum -= root->val; // 更新当前路径的和if (sum == 0 && root->left == NULL && root->right == NULL) { // 找到和为target的路径struct TreeNode* path = (structTreeNode*)malloc(sizeof(struct TreeNode));path->val = root->val;path->left = NULL;path->right = NULL;*paths[*pathSize] = path;(*pathSize)++;return;}findPaths(root->left, target, sum, paths, pathSize); // 递归遍历左子树findPaths(root->right, target, sum, paths, pathSize); // 递归遍历右子树}int main() {// 构造一棵二叉树struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));root->val = 5;root->left = (struct TreeNode*)malloc(sizeof(struct TreeNode));root->left->val = 4;root->left->left = NULL;root->left->right = NULL;root->right = (struct TreeNode*)malloc(sizeof(struct TreeNode));root->right->val = 8;root->right->left = (struct TreeNode*)malloc(sizeof(struct TreeNode));root->right->left->val = 11;root->right->left->left = NULL;root->right->left->right = NULL;root->right->right = (struct TreeNode*)malloc(sizeof(struct TreeNode));root->right->right->val = 7;root->right->right->left = NULL;root->right->right->right = NULL;// 查找和为target的路径int target = 22;struct TreeNode** paths = NULL; // 存储路径的数组int pathSize = 0; // 路径数组的大小findPaths(root, target, target, &paths, &pathSize);// 输出找到的路径printf("Paths sum to %d:\n", target);for (int i = 0; i < pathSize; i++) {struct TreeNode* path = paths[i];while (path != NULL) {printf("%d ", path->val);path = path->left;}printf("\n");free(paths[i]); // 释放路径所占用的内存空间}free(paths); // 释放路径数组所占用的内存空间return 0;}```。

二叉排序树的c语言代码

二叉排序树的c语言代码

二叉排序树(Binary Sort Tree)是一种特殊的二叉树,它或左子树或右子树为完全二叉树。

由于二叉排序树的特点,其每个节点的值均大于其左子树中的所有节点的值,且小于其右子树中的所有节点的值。

以下是一个简单的二叉排序树的C语言实现,包括插入、查找和删除操作。

```c#include <stdio.h>#include <stdlib.h>typedef struct Node {int data;struct Node *left;struct Node *right;} Node;// 创建一个新的节点Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node));if (!newNode) {printf("内存分配失败\n");return NULL;}newNode->data = data;newNode->left = newNode->right = NULL;return newNode;}// 在二叉排序树中插入一个新的节点Node* insert(Node* root, int data) {if (!root) { // 如果树为空,创建新节点并返回根节点root = createNode(data);} else if (data <= root->data) { // 如果插入的数据小于当前节点的值,则在左子树中插入root->left = insert(root->left, data);} else { // 如果插入的数据大于当前节点的值,则在右子树中插入root->right = insert(root->right, data);}return root; // 返回插入后的根节点}// 在二叉排序树中查找一个值是否存在int search(Node* root, int data) {if (!root) { // 如果树为空,返回0表示未找到return 0;} else if (root->data == data) { // 如果找到,返回1表示找到return 1;} else if (data < root->data) { // 如果插入的数据小于当前节点的值,在左子树中查找return search(root->left, data);} else { // 如果插入的数据大于当前节点的值,在右子树中查找return search(root->right, data);}}// 在二叉排序树中删除一个节点,并返回被删除的节点指针(如果存在)Node* deleteNode(Node* root, int data) {if (!root) return NULL; // 如果树为空,直接返回NULL(空树)if (data < root->data) { // 如果要删除的值小于当前节点的值,则在左子树中查找并删除root->left = deleteNode(root->left, data);} else if (data > root->data) { // 如果要删除的值大于当前节点的值,则在右子树中查找并删除root->right = deleteNode(root->right, data);} else { // 如果要删除的节点就是当前节点,根据情况选择删除方式(左子树或右子树)if (root->left == NULL) { // 如果左子树为空,直接删除当前节点(只有根节点时)Node *temp = root; // 临时保存当前节点,用于释放内存后替换原节点指针为NULLfree(temp); // 释放内存空间后将原指针设为NULL} else if (root->right == NULL) { // 如果右子树为空,直接删除当前节点(只有一个节点时)Node *temp = root->left; // 临时保存左子树的根节点,用于替换原节点指针为左子树的根节点指针(此时原节点为空)free(root); // 释放原节点的内存空间后将原指针设为NULL(此时原节点为空)root = temp; // 将原指针设为新的根节点指针(此时原节点为空)} else { // 如果左右子树都存在,则找到右子树中的最小节点(即要被替换的节点),替换原节点指针为最小节点的指针(此时原节点为空)并删除最小节点(通过递归实现)Node *temp = root->right; // 临时保存右子树的根节点指针(即要被替换的节点)root->data = temp->data; // 将原节点的数据。

二叉树计算叶子节点的算法C语言版

二叉树计算叶子节点的算法C语言版

二叉树计算叶子节点的算法C语言版二叉树是一种常见的数据结构,其中每个节点最多有两个子节点:左子节点和右子节点。

叶子节点是指没有子节点的节点。

计算二叉树的叶子节点数量可以通过递归或迭代来实现。

在本文中,我们将探讨在C语言中实现计算叶子节点的算法。

1.定义节点结构体首先,我们需要定义一个包含二叉树节点信息的结构体。

节点结构体应该至少包含一个整数值来保存节点的数据,并且需要包含指向左子节点和右子节点的指针。

```ctypedef struct TreeNodeint data;struct TreeNode* left;struct TreeNode* right;} TreeNode;```2.创建二叉树在开始计算叶子节点之前,我们需要先创建一个二叉树。

为了简化问题,我们将手动创建一个具有固定节点值的二叉树。

```cTreeNode* createBinaryTre//创建节点TreeNode* root = createNode(1); TreeNode* node2 = createNode(2); TreeNode* node3 = createNode(3); TreeNode* node4 = createNode(4); TreeNode* node5 = createNode(5); TreeNode* node6 = createNode(6); TreeNode* node7 = createNode(7); //连接节点root->left = node2;root->right = node3;node2->left = node4;node2->right = node5;node3->left = node6;node3->right = node7;return root;```在上面的代码中,我们使用`createNode`函数创建节点,并使用`->`运算符将节点连接起来形成一个二叉树。

二叉树c语言实现完整代码

二叉树c语言实现完整代码

二叉树c语言实现完整代码二叉树是一种非常常见的数据结构,它由节点和边组成,每个节点最多有两个子节点,分别称为左子节点和右子节点。

在计算机科学中,二叉树被广泛应用于搜索、排序、编译器等领域。

本文将介绍如何使用C语言实现二叉树的完整代码。

我们需要定义二叉树的节点结构体。

每个节点包含三个成员变量:数据、左子节点和右子节点。

代码如下:```struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;};```接下来,我们需要实现二叉树的基本操作,包括创建节点、插入节点、删除节点、查找节点等。

这些操作可以通过递归实现。

代码如下:```// 创建节点struct TreeNode* createNode(int val) {struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));node->val = val;node->left = NULL;node->right = NULL;return node;}// 插入节点struct TreeNode* insertNode(struct TreeNode* root, int val) {if (root == NULL) {return createNode(val);}if (val < root->val) {root->left = insertNode(root->left, val);} else {root->right = insertNode(root->right, val);}return root;}// 删除节点struct TreeNode* deleteNode(struct TreeNode* root, int val) {if (root == NULL) {return NULL;}if (val < root->val) {root->left = deleteNode(root->left, val);} else if (val > root->val) {root->right = deleteNode(root->right, val);} else {if (root->left == NULL) {struct TreeNode* temp = root->right;free(root);return temp;} else if (root->right == NULL) {struct TreeNode* temp = root->left;free(root);return temp;}struct TreeNode* temp = findMin(root->right); root->val = temp->val;root->right = deleteNode(root->right, temp->val); }return root;}// 查找节点struct TreeNode* searchNode(struct TreeNode* root, int val) {if (root == NULL || root->val == val) {return root;}if (val < root->val) {return searchNode(root->left, val);} else {return searchNode(root->right, val);}}// 查找最小节点struct TreeNode* findMin(struct TreeNode* root) {while (root->left != NULL) {root = root->left;}return root;}```我们需要实现二叉树的遍历操作,包括前序遍历、中序遍历和后序遍历。

数据结构-C语言-树和二叉树

数据结构-C语言-树和二叉树

练习
一棵完全二叉树有5000个结点,可以计算出其
叶结点的个数是( 2500)。
二叉树的性质和存储结构
性质4: 具有n个结点的完全二叉树的深度必为[log2n]+1
k-1层 k层
2k−1−1<n≤2k−1 或 2k−1≤n<2k n k−1≤log2n<k,因为k是整数
所以k = log2n + 1
遍历二叉树和线索二叉树
遍历定义
指按某条搜索路线遍访每个结点且不重复(又称周游)。
遍历用途
它是树结构插入、删除、修改、查找和排序运算的前提, 是二叉树一切运算的基础和核心。
遍历规则 D
先左后右
L
R
DLR LDR LRD DRL RDL RLD
遍历规则
A BC DE
先序遍历:A B D E C 中序遍历:D B E A C 后序遍历:D E B C A
练习 具有3个结点的二叉树可能有几种不同形态?普通树呢?
5种/2种
目 录 导 航 Contents
5.1 树和二叉树的定义 5.2 案例引入 5.3 树和二叉树的抽象数据类型定义 5.4 二叉树的性质和存储结构 5.5 遍历二叉树和线索二叉树 5.6 树和森林 5.7 哈夫曼树及其应用 5.8 案例分析与实现
(a + b *(c-d)-e/f)的二叉树
目 录 导 航 Contents
5.1 树和二叉树的定义 5.2 案例引入 5.3 树和二叉树的抽象数据类型定义 5.4 二叉树的性质和存储结构 5.5 遍历二叉树和线索二叉树 5.6 树和森林 5.7 哈夫曼树及其应用 5.8 案例分析与实现
二叉树的抽象数据类型定义
特殊形态的二叉树
只有最后一层叶子不满,且全部集中在左边

二叉树 c语言

二叉树 c语言

二叉树 c语言在计算机科学领域中,树型数据结构是一种非常重要的数据结构,在实际开发中也得到了广泛的应用。

其中,二叉树又是一种非常常见的树型结构。

二叉树在很多情况下都能够提供更好的算法效率,同时也易于理解和实现,因此我们可以通过通过学习和掌握二叉树的特点以及优点,来更好的应用到实际开发中。

一、二叉树的定义二叉树是一种树型结构,树型结构是由节点构成的。

二叉树与一般的树型结构不同,它的每个节点最多只有两个子节点,分别称为左子树和右子树。

它们可以为空或者不为空,其子节点的数量时不固定且没有任何限制的。

二叉树的定义如下:(1)空树是树的一种特殊的状态。

我们可以把它称为二叉树;(2)若不是空树,那么它就是由一个称为根节点(root)的元素和左右两棵分别称为左子树(left subtree)和右子树(right subtree)的二叉树组成。

二、二叉树的特性(1)每个节点最多只有两个子节点,分别称为左子节点和右子节点;(2)左子树和右子树是二叉树;(3)二叉树没有重复的节点。

三、二叉树的应用二叉树是一种非常实用的数据结构,因为它可以模拟很多实际生活中的情况。

例如,我们可以利用二叉树来对某些数据进行分类和排序。

在二叉树的基础上,我们还可以构造二叉堆、哈夫曼树等更高级的数据结构。

除此之外,二叉树还可以应用到程序设计中。

例如,我们可以构造一个二叉树来表示某个程序的控制流,这个程序在执行时可以沿着二叉树的各个节点进行分支和选择,实现不同的功能。

此外,我们还可以利用二叉树来加快某些算法的执行效率,比如二分查找算法等。

四、二叉树的遍历方式对于二叉树的遍历,有三种基本方式,即前序遍历、中序遍历、后序遍历。

它们的遍历顺序不同,因此也得到了不同的称呼。

下面我们来简要介绍一下这三种遍历方式的特点和应用。

(1)前序遍历前序遍历是指首先访问树的根节点,然后按照从左到右的顺序依次遍历左子树和右子树。

前序遍历的应用非常广泛,可以用于生成表达式树、构造二叉树等等。

C语言二叉树的实际应用场景

C语言二叉树的实际应用场景

C语言二叉树的实际应用场景
树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构,很像自然界中的树那样。

树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形象表示。

树在计算机领域中也得到广泛应用,如在编译源程序如下时,可用树表示源程序如下的语法结构。

又如在数据库系统中,树型结构也是信息的重要组织形式之一。

一切具有层次关系的问题都可用树来描述。

分为满二叉树,完全二叉树,排序二叉树。

1、哈夫曼编码,来源于哈夫曼树【给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为赫夫曼树(Huffman tree)。

即带权路径长度最短的树】,在数据压缩上有重要应用,提高了传输的有效性,详见《信息论与编码》。

2、海量数据并发查询,二叉树复杂度是O(K+LgN)。

二叉排序树就既有链表的好处,也有数组的好处,在处理大批量的动态的数据是比较有用。

3、C++STL中的set/multiset、map,以及Linux虚拟内存的管理,都是通过红黑树去实现的。

查找最大(最小)的k个数,红黑树,红黑树中查找/删除/插入,都只需要O(logk)。

4、B-Tree,B+-Tree在文件系统中的目录应用。

5、路由器中的路由搜索引擎。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/************************************************************************/二叉树在C语言中的实现与应用/************************************************************************/#include <stdio.h>#include <stdlib.h>#define STACK_MAX_SIZE 30#define QUEUE_MAX_SIZE 30#ifndef elemTypetypedef char elemType;#endif/************************************************************************//* 以下是关于二叉树操作的11个简单算法 *//************************************************************************/ struct BTreeNode{elemType data;struct BTreeNode *left;struct BTreeNode *right;};/* 1.初始化二叉树 */void initBTree(struct BTreeNode* *bt){*bt = NULL;return;}/* 2.建立二叉树(根据a所指向的二叉树广义表字符串建立) */void createBTree(struct BTreeNode* *bt, char *a){struct BTreeNode *p;struct BTreeNode *s[STACK_MAX_SIZE];/* 定义s数组为存储根结点指针的栈使用 */int top = -1; /* 定义top作为s栈的栈顶指针,初值为-1,表示空栈 */int k; /* 用k作为处理结点的左子树和右子树,k = 1处理左子树,k = 2处理右子树 */ int i = 0; /* 用i扫描数组a中存储的二叉树广义表字符串,初值为0 */*bt = NULL; /* 把树根指针置为空,即从空树开始建立二叉树 *//* 每循环一次处理一个字符,直到扫描到字符串结束符\0为止 */while(a[i] != '\0'){switch(a[i]){case ' ':break; /* 对空格不作任何处理 */case '(':if(top == STACK_MAX_SIZE - 1){printf("栈空间太小!\n");exit(1);}top++;s[top] = p;k = 1;break;case ')':if(top == -1){printf("二叉树广义表字符串错误!\n");exit(1);}top--;break;case ',':k = 2;break;default:p = new BTreeNode ;p->data = a[i];p->left = p->right = NULL;if(*bt == NULL){*bt = p;}else{if( k == 1){s[top]->left = p;}else{s[top]->right = p;}}}i++; /* 为扫描下一个字符修改i值 */}return;}/* 3.检查二叉树是否为空,为空则返回1,否则返回0 */ int emptyBTree(struct BTreeNode *bt){if(bt == NULL){return 1;}else{return 0;}}/* 4.求二叉树深度 */int BTreeDepth(struct BTreeNode *bt){if(bt == NULL){return 0; /* 对于空树,返回0结束递归 */}else{int dep1 = BTreeDepth(bt->left); /* 计算左子树的深度 */int dep2 = BTreeDepth(bt->right); /* 计算右子树的深度 */if(dep1 > dep2){return dep1 + 1;}else{return dep2 + 1;}}}/* 5.从二叉树中查找值为x的结点,若存在则返回元素存储位置,否则返回空值 */ elemType *findBTree(struct BTreeNode *bt, elemType x){if(bt == NULL){return NULL;}else{if(bt->data == x){return &(bt->data);}else{ /* 分别向左右子树递归查找 */elemType *p;if(p = findBTree(bt->left, x)){return p;}if(p = findBTree(bt->right, x)){return p;}return NULL;}}}/* 6.输出二叉树(前序遍历) */void printBTree(struct BTreeNode *bt){/* 树为空时结束递归,否则执行如下操作 */if(bt != NULL){printf("%c", bt->data); /* 输出根结点的值 */if(bt->left != NULL || bt->right != NULL){printf("(");printBTree(bt->left);if(bt->right != NULL){printf(",");}printBTree(bt->right);printf(")");}}return;}/* 7.清除二叉树,使之变为一棵空树 */void clearBTree(struct BTreeNode* *bt) {if(*bt != NULL){clearBTree(&((*bt)->left));clearBTree(&((*bt)->right));free(*bt);*bt = NULL;}return;}/* 8.前序遍历 */void preOrder(struct BTreeNode *bt){if(bt != NULL){printf("%c ", bt->data); /* 访问根结点 */ preOrder(bt->left); /* 前序遍历左子树 */ preOrder(bt->right); /* 前序遍历右子树 */ }return;}/* 9.前序遍历 */void inOrder(struct BTreeNode *bt){if(bt != NULL){inOrder(bt->left); /* 中序遍历左子树 */ printf("%c ", bt->data); /* 访问根结点 */ inOrder(bt->right); /* 中序遍历右子树 */ }return;}/* 10.后序遍历 */void postOrder(struct BTreeNode *bt){if(bt != NULL){postOrder(bt->left); /* 后序遍历左子树 */ postOrder(bt->right); /* 后序遍历右子树 */ printf("%c ", bt->data); /* 访问根结点 */ }return;}/* 11.按层遍历 */void levelOrder(struct BTreeNode *bt){struct BTreeNode *p;struct BTreeNode *q[QUEUE_MAX_SIZE];int front = 0, rear = 0;/* 将树根指针进队 */if(bt != NULL){rear = (rear + 1) % QUEUE_MAX_SIZE;q[rear] = bt;}while(front != rear){ /* 队列非空 */front = (front + 1) % QUEUE_MAX_SIZE; /* 使队首指针指向队首元素 */p = q[front];printf("%c ", p->data);/* 若结点存在左孩子,则左孩子结点指针进队 */if(p->left != NULL){rear = (rear + 1) % QUEUE_MAX_SIZE;#include <stdio.h>#include <stdlib.h>#define STACK_MAX_SIZE 30#define QUEUE_MAX_SIZE 30#ifndef elemTypetypedef char elemType ;#endif/************************************************************************//* 以下是关于二叉树操作的11个简单算法 *//************************************************************************/struct BTreeNode{elemType data ;struct BTreeNode *left ;struct BTreeNode *right ;};/* 1.初始化二叉树 */void initBTree(struct BTreeNode* *bt){*bt = NULL ;return ;}/* 2.建立二叉树(根据a所指向的二叉树广义表字符串建立) */void createBTree(struct BTreeNode* *bt, char *a){struct BTreeNode *p;struct BTreeNode *s[STACK_MAX_SIZE];/* 定义s数组为存储根结点指针的栈使用 */int top = -1; /* 定义top作为s栈的栈顶指针,初值为-1,表示空栈 */int k ; /* 用k作为处理结点的左子树和右子树,k = 1处理左子树,k = 2处理右子树 */ int i = 0 ; /* 用i扫描数组a中存储的二叉树广义表字符串,初值为0 */*bt = NULL ; /* 把树根指针置为空,即从空树开始建立二叉树 *//* 每循环一次处理一个字符,直到扫描到字符串结束符\0为止 */ while(a[i] != '\0'){switch(a[i]){case ' ':break; /* 对空格不作任何处理 */case '(':if( top == STACK_MAX_SIZE - 1 ){printf("栈空间太小!\n") ;exit(1) ;}top++ ;s[top] = p ;k = 1 ;break;case ')':if(top == -1){printf("二叉树广义表字符串错误!\n");exit(1);}top-- ;break ;case ',':k = 2;break;default:p = new BTreeNode ;p->data = a[i] ;p->left = p->right = NULL ;if( *bt == NULL){*bt = p ;}else{if( k == 1){s[top]->left = p ;}else{s[top]->right = p ;}}}i++ ; /* 为扫描下一个字符修改i值 */}return;}/* 3.检查二叉树是否为空,为空则返回1,否则返回0 */int emptyBTree(struct BTreeNode *bt){if(bt == NULL){return 1;}else{return 0;}}/* 4.求二叉树深度 */int BTreeDepth(struct BTreeNode *bt){if(bt == NULL){return 0; /* 对于空树,返回0结束递归 */}else{int dep1 = BTreeDepth(bt->left); /* 计算左子树的深度 */int dep2 = BTreeDepth(bt->right); /* 计算右子树的深度 */if(dep1 > dep2){return dep1 + 1;}else{return dep2 + 1;}}}/* 5.从二叉树中查找值为x的结点,若存在则返回元素存储位置,否则返回空值 */ elemType *findBTree(struct BTreeNode *bt, elemType x){if(bt == NULL){return NULL;}else{if(bt->data == x){return &(bt->data);}else{ /* 分别向左右子树递归查找 */elemType *p ;if(p = findBTree(bt->left, x)){return p ;}if(p = findBTree(bt->right, x)){return p ;}return NULL ;}}}/* 6.输出二叉树(前序遍历) */void printBTree(struct BTreeNode *bt){/* 树为空时结束递归,否则执行如下操作 */if(bt != NULL){printf("%c ", bt->data); /* 输出根结点的值 */ if(bt->left != NULL || bt->right != NULL){printf("(") ;printBTree(bt->left) ;if(bt->right != NULL){printf(",") ;}printBTree(bt->right) ;printf(")");}}return;}/* 7.清除二叉树,使之变为一棵空树 */void clearBTree(struct BTreeNode* *bt){if(*bt != NULL){clearBTree(&((*bt)->left)) ;clearBTree(&((*bt)->right)) ;free(*bt) ;*bt = NULL ;}return ;}/* 8.前序遍历 */void preOrder(struct BTreeNode *bt){if(bt != NULL){printf("%c ", bt->data) ; /* 访问根结点 */ preOrder(bt->left) ; /* 前序遍历左子树 */ preOrder(bt->right) ; /* 前序遍历右子树 */}return ;}/* 9.中序遍历 */void inOrder(struct BTreeNode *bt){if(bt != NULL){inOrder(bt->left); /* 中序遍历左子树 */printf("%c ", bt->data); /* 访问根结点 */inOrder(bt->right); /* 中序遍历右子树 */}return;}/* 10.后序遍历 */void postOrder(struct BTreeNode *bt){if(bt != NULL){postOrder(bt->left); /* 后序遍历左子树 */postOrder(bt->right); /* 后序遍历右子树 */printf("%c ", bt->data); /* 访问根结点 */}return;}/* 11.按层遍历 */void levelOrder(struct BTreeNode *bt){struct BTreeNode *p;struct BTreeNode *q[QUEUE_MAX_SIZE];int front = 0, rear = 0;/* 将树根指针进队 */if(bt != NULL){rear = (rear + 1) % QUEUE_MAX_SIZE;q[rear] = bt;}while(front != rear){ /* 队列非空 */front = (front + 1) % QUEUE_MAX_SIZE; /* 使队首指针指向队首元素 */ p = q[front];printf("%c ", p->data);/* 若结点存在左孩子,则左孩子结点指针进队 */if(p->left != NULL){rear = (rear + 1) % QUEUE_MAX_SIZE;q[rear] = p->left;}/* 若结点存在右孩子,则右孩子结点指针进队 */if(p->right != NULL){rear = (rear + 1) % QUEUE_MAX_SIZE;q[rear] = p->right;}}return;}/************************************************************************/int main(int argc, char *argv[]){struct BTreeNode *bt ; /* 指向二叉树根结点的指针 */char *b ; /* 用于存入二叉树广义表的字符串 */elemType x, *px ;initBTree(&bt) ;printf("输入二叉树广义表的字符串:\n") ;/* scanf("%s", b); */b = "a(b(c), d(e(f, g), h(, i)))" ; //////其中不在括号中的字符表示的是根节点括号中的分别是左右儿子createBTree(&bt, b) ;if(bt != NULL)printf(" %c ", bt->data) ;printf("以广义表的形式输出:\n") ;printBTree(bt); /* 以广义表的形式输出二叉树 */printf("\n");printf("前序:"); /* 前序遍历 */preOrder(bt);printf("\n");printf("中序:"); /* 中序遍历 */inOrder(bt);printf("\n");printf("后序:"); /* 后序遍历 */postOrder(bt);printf("\n");printf("按层:"); /* 按层遍历 */levelOrder(bt);printf("\n");/* 从二叉树中查找一个元素结点 */printf("输入一个待查找的字符:\n");scanf(" %c", &x); /* 格式串中的空格跳过空白字符 */px = findBTree(bt, x);if(px){printf("查找成功:%c\n", *px);}else{printf("查找失败!\n");}printf("二叉树的深度为:");printf("%d\n", BTreeDepth(bt));clearBTree(&bt);return 0;}。

相关文档
最新文档