系列文章目录

其他章节相关文章

王道——数据结构——栈和队列(1)

本章节其他相关文章

王道——数据结构——树与二叉树(1)
王道——数据结构——树与二叉树(2)
王道——数据结构——树与二叉树(4)


文章目录

  • 系列文章目录
    • 其他章节相关文章
    • 本章节其他相关文章
  • 前言
  • 一、5.3节

前言

本文为王道数据结构的第五章——树与二叉树的编程题。
运行软件:vscode
使用c++文件编写
本文所使用的树为《王道——数据结构——树与二叉树(1)》中建立的树


一、5.3节

11、已知二叉树以二叉链表存储,编写算法完成:对于树中的每个元素值为x的结点,删去以它为根节点的子树,并释放相应的空间。

// 第十一题 使用层次遍历主树,发现结点值为x时,对x的子树进行后续遍历,访问各结点时删除结点
// 复杂版
void test11(){BiTree T;InitBiTree(T);buildTree(T);PreOrder(T);int x;printf("\n请输入你想删除的元素值:");scanf("%d", &x);BiTNode *p, *temp, *last, *par;LinkQueue Q;  // 使用队列进行层次遍历,只有结点不为x的值才能入队InitLinkQueue(Q);LinkStack S;InitLinkStack(S); // 使用栈进行后续遍历EnQueue(Q, T);while(Q.front->next != NULL){DeQueue(Q, p);temp = p->lchild;if(temp && temp->data.value == x){  // 删去以x为根节点的子树while (temp || S != NULL){if(temp){Push(S, temp);temp = temp->lchild;}else{if(S->data->rchild != last && S->data->rchild != NULL)temp = S->data->rchild;else{Pop(S, last);free(last);}}}p->lchild = NULL;}else if(temp != NULL)EnQueue(Q, p->lchild);temp = p->rchild;if(temp && temp->data.value == x){  // 删去以x为根节点的子树while (temp || S != NULL){if(temp){Push(S, temp);temp = temp->lchild;}else{if(S->data->rchild != last && S->data->rchild != NULL)temp = S->data->rchild;else{Pop(S, last);free(last);}}}p->rchild = NULL;}else if(p->rchild != NULL)EnQueue(Q, p->rchild);}PreOrder(T);
}// 简洁版 通过函数调用实现
void Delechild(BiTree T){if(T->lchild != NULL)Delechild(T->lchild);if(T->rchild != NULL)Delechild(T->rchild);free(T);
}void test11_2(){BiTree T;InitBiTree(T);buildTree(T);PreOrder(T);int x;printf("\n请输入你想删除的元素值:");scanf("%d", &x);BiTNode *p;LinkQueue Q;  // 使用队列进行层次遍历,只有结点不为x的值才能入队InitLinkQueue(Q);EnQueue(Q, T);while(Q.front->next != NULL){DeQueue(Q, p);if(p->lchild != NULL){if(p->lchild->data.value == x){Delechild(p->lchild);p->lchild = NULL;}elseEnQueue(Q, p->lchild);}if(p->rchild != NULL){if(p->rchild->data.value == x){Delechild(p->rchild);p->rchild = NULL;}elseEnQueue(Q, p->rchild);}}PreOrder(T);
}

12、在二叉树中查找值为x的结点,试编写算法(用C语言)打印值为x的结点的所有祖先节点,假设值为x的结点不多于一个

// 第十二题(用C) 使用后续遍历,设立标志tag=0,当发现x时tag变为1,访问节点时判断tag是否为1,如果为1打印输出该结点
int test12(BiTree T, int x, int tag){if(T->data.value == x)tag = 1;if(tag == 0 && T->lchild != NULL)tag = test12(T->lchild, x, tag);if(tag == 0 && T->rchild != NULL)tag = test12(T->rchild, x, tag);if(tag == 1 && T->data.value != x)printf("%d ", T->data.value);return tag;// 运行代码// BiTree T;// InitBiTree(T);// buildTree(T);// int x, tag = 0;// printf("请输入你想查找的数字:");// scanf("%d", &x);// x = test12(T, x, tag);
}

13、设一棵二叉树的结点结构为(LLINK,INFO,RLINK),ROOT为指向该二叉树根节点的指针,p和q分别为指向二叉树中任意两个结点的指针,试编写算法ANCESTOR(ROOT, p, q, r),找到p和q的最近公共结点r。

// 第十三题 使用后续遍历的方法建立两个栈分别保存p,q的祖先结点,假设p在q左边,则必先遍历到p再遍历到q
// 使用新的栈对两个栈进行逆置,分别对两个新的栈进行遍历找到最近公共结点
// 找a结点所有的祖先节点并保存在栈中
LinkStack Stackparent(BiTree T, int a){LinkStack S;InitLinkStack(S);BiTNode *p = T, *last;while (p || S!= NULL){if(p){Push(S, p);p = p->lchild;}else{if(S->data->rchild != NULL && S->data->rchild != last)p = S->data->rchild;else{if(S->data->data.value == a)break;Pop(S, last);}}}return S;
}void test13(){BiTree T;InitBiTree(T);buildTree(T);printf("请输入你想查找的第一个结点值:");int a, b;scanf("%d", &a);printf("请输入你想查找的第二个结点值:");scanf("%d", &b);LinkStack S1, S2, SN1, SN2;InitLinkStack(S1);InitLinkStack(S2);InitLinkStack(SN1);InitLinkStack(SN2);BiTNode *temp;S1 = Stackparent(T, a);  // 找a的所有祖先节点S2 = Stackparent(T, b);  // 找b的所有祖先结点while(S1 != NULL){  // 将S1逆置Pop(S1, temp);Push(SN1, temp);}while(S2 != NULL){  // 将S2逆置Pop(S2, temp);Push(SN2, temp);}StackNode *p = SN1, *q = SN2;while(p->next != NULL && q->next != NULL){  // 如果遍历的其中一个栈的最后一个元素还没有找到不同的元素,那么其中一个结点是另一个结点的孩子结点if(p->next->data == q->next->data){  // 从一棵树找到的两个结点,根节点肯定是公共结点,这里直接从第二个结点开始计算 p = p->next;q = q->next;}elsebreak;}printf("最近公共结点值为:%d",p->data->data.value);
}

14、假设二叉树采用二叉链表存储结构,设计一个算法,求非空二叉树b的宽度。


// 第十四题 使用队列进行层次遍历,用weigh计算每层结点个数,weighest保存最宽的层结点数
// 使用last指针指向每层的最后一个元素,当访问到last指针时,last指针指向下一层最后一个元素
void test14(){BiTree T;InitBiTree(T);buildTree(T);LinkQueue Q;InitLinkQueue(Q);BiTNode *p = T, *last = T;int weight = 0, weightest = 0;EnQueue(Q, p);while(Q.front->next != NULL){DeQueue(Q, p);weight++;if(p->lchild != NULL)EnQueue(Q, p->lchild);if(p->rchild != NULL)EnQueue(Q, p->rchild);if(p == last){last = Q.rear->data;if(weight > weightest)weightest = weight;weight = 0;}}printf("树的宽度:%d", weightest);
}

15、设有一棵满二叉树(所有结点值均不同),已知其先序序列为pre,设计一个算法求其后序序列post。

// 第十五题 将先序序列的第一个元素放到后序序列的最后一个元素上,先序序列除了第一个元素剩下的所有元素为左右子树的总和——根左右
// 左子树为其二分之一,将左子树从后序序列第一个位置开始防止,然后放右子树
// l1为先序序列的开始位置,h1为先序序列的最后一个元素位置,l2为后序序列开始位置,h2为后序序列最后一个元素位置
void GetPostOrder(int pre[], int l1, int h1, int post[7], int l2, int h2){if(l1<=h1){post[h2] = pre[l1];int half;half = (h1-l1)/2;GetPostOrder(pre, l1+1, l1+half, post, l2, l2+half-1);GetPostOrder(pre, l1+half+1, h1, post, l2+half, h2-1); }
}void test15(){int pre[7] = {1,2,4,5,3,6,7};int post[7];GetPostOrder(pre, 0, 6, post, 0, 6);printf("后序序列:");for (int i = 0; i<7; i++){printf("%d ", post[i]);}
}

16、设计一个算法将二叉树的叶节点按从左到右的顺序连成一个单链表,表头指针为head。二叉树按二叉链表方式存储,链接时用叶节点的右指针域来存放单链表指针。

// 第十六题  使用栈对二叉树进行后序遍历,找到叶子结点,将pre指针指向叶子结点,找到下一个叶子结点时,将pre的右孩子指向该结点,并将pre指向该结点
void test16(){BiTree T;InitBiTree(T);buildTree(T);LinkStack S;InitLinkStack(S);BiTNode *p = T, *pre = NULL, *last, *temp, *testnode;while(p || S!=NULL){if(p){Push(S, p);p =p->lchild;}else{if(S->data->rchild != NULL && S->data->rchild != last)p = S->data->rchild;else{Pop(S, temp);if(temp->lchild == NULL && temp->rchild == NULL){if(pre)pre->rchild = temp;pre = temp;}last = temp;}}}p = T;while(p->lchild != NULL )  // 为了方便测试,树做左边必须有一个叶子节点p = p->lchild;while(p != NULL){printf("%d ", p->data.value);p = p->rchild;}}

17、试设计判断两棵树是否相似的算法。所谓二叉树T1和T2相似,指的是T1和T2都是空的二叉树或都只有一个根节点;或T1的左子树和T2的左子树相似,且T1的右子树和T2的右子树相似。

// 第十七题 相似:树的结构相同,形状相同,元素可以不同,使用标志位tag记录结构是否相同,1代表相同,0代表不同
void same(BiTree T1, BiTree T2, int &tag){if(tag == 0)return;if(T1 == NULL && T2 != NULL){tag = 0;}else if(T1 != NULL && T2 == NULL){tag = 0;}else if(T1 != NULL){same(T1->lchild, T2->lchild, tag);same(T1->rchild, T2->rchild, tag);}return;
}void test17(){BiTree T1, T2;printf("下面建立第一棵树\n");InitBiTree(T1);buildTree(T1);printf("下面建立第二棵树\n");InitBiTree(T2);buildTree(T2);int tag = 1;same(T1, T2, tag);if(tag == 1)printf("两棵树相似");else    printf("两棵树不相似");
}

18、写出在中序线索二叉树里查找指定结点在后序的前驱结点算法。

// 第十八题 找后序线索二叉树指定节点的前驱结点,如果该结点的有右孩子不为空,则前驱结点为右孩子
// 如果该结点的右孩子为空但左孩子不为空,则前驱结点为左孩子
// 如果该结点的左右孩子都为空,则前驱结点为该结点祖先节点中最近的且不被访问过的左孩子
void test18_1(ThreadTree T, ThreadNode *p){if(p->rtag == 0)printf("%d", p->rchild->data.value);else if(p->ltag == 0)printf("%d", p->lchild->data.value);else{while(p->lchild != NULL && p->ltag != 0)p = p->lchild;if(p->lchild != NULL)printf("%d", p->lchild->data.value);else    printf("该结点为后序遍历的第一个结点,没有前驱结点");}
}void test18(){ThreadTree T;InitThreadTree(T);buildTree(T);CreatTheadThree(T);Inorder(T);int x;printf("\n请输入你想要查询的数:");scanf("%d", &x);ThreadNode *p = T, *first;while(p->ltag == 0)p = p->lchild;while(p->data.value != x){if(p->rtag != 0)p = p->rchild;else{first = p->rchild;while(first->ltag == 0)first = first->lchild;p = first;}}printf("%d\n", p->data.value);test18_1(T, p);
}

19、二叉树的带权路径长度(WPL)是二叉树中所有叶结点的带权路径长度之和。给定一棵二叉树T,采用二叉链表存储,结点结构为:(left, weight, right),其中叶结点的weight域保存该结点的非负权值。设root为指向T的根结点的指针,请设计求T的WPL的算法。要求:

(1)给出算法的基本设计思想;

(2)使用C或C++语言,给出二叉树结点的数据类型定义;

(3)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。

// 第十九题 采用队列实现二叉树的层次遍历,使用last标记每层最后一个元素,high记录层数,每个结点的带权路径长度为high*weight
// 树的带权路径长度为所有结点带权路径长度之和
typedef struct WPLNode{int weight;struct WPLNode *left, *right;
}WPLNode, *WPLTree;void test19(){BiTree T;InitBiTree(T);buildTree(T);LinkQueue Q;InitLinkQueue(Q);BiTNode *p, *last = T;int high = 1, sum = 0;EnQueue(Q, T);while(Q.front->next != NULL){DeQueue(Q, p);sum += high*p->data.value;if(p->lchild)EnQueue(Q, p->lchild);if(p->rchild)EnQueue(Q, p->rchild);if(p == last){high++;last = Q.rear->data;}}printf("%d", sum);
}

20、二叉树–请设计一个算法,将给定的表达式树(二叉树)转换为等价的中缀表达式(通过括号反映操作符的计算次序)并输出。

// 第二十题 使用递归实现对二叉树的中序遍历,在访问结点时,加上左右括号,根节点和叶子节点不加括号
void test20_1(BiTNode *p, int &deep){if(deep != 1 ) // 根节点不加括号if(p->lchild != NULL || p->rchild != NULL)  // 叶子结点不加括号printf("( ");if(p->lchild != NULL){deep++;test20_1(p->lchild, deep);deep--;}printf("%d ", p->data.value);if(p->rchild != NULL){deep++;test20_1(p->rchild, deep);deep--;}if(deep != 1)if(p->lchild != NULL || p->rchild != NULL)printf(") ");
}void test20(){BiTree T;InitBiTree(T);buildTree(T);int deep = 1;test20_1(T, deep);
}

王道——数据结构——树与二叉树(3)相关推荐

  1. 数据结构-树与二叉树-思维导图+小结

    数据结构-树与二叉树-思维导图 1 数据结构-第五章-树与二叉树-思维导图 2 思维导图-补充 3 小结 3.1 知识点小结 3.2 习题小结 1 数据结构-第五章-树与二叉树-思维导图   数据结构 ...

  2. 数据结构——树和二叉树章节思维导图

    数据结构--树和二叉树章节思维导图

  3. 数据结构—树与二叉树

    总第119篇 前言 之前谈到的线性表.栈和队列都是一对一的数据结构,但是现实中也存在很多一对多的数据结构,这篇要写的就是一种一对多的数据结构---树.全文分为如下几部分: 树的一些基本概念 树的存储结 ...

  4. C语言 数据结构 树和二叉树

    树 1.树:是n节点的有限集.树是n(n=>0)个节点的有限集. n=0时成为空树. 在任意一颗非空树中:(1)有且仅有一个称为根的节点:(2)当n>0时,其余节点可分为m(m>0) ...

  5. 数据结构-树,二叉树,森林

    树,二叉树,森林 王卓老师的数据结构课程笔记 树和二叉树 定义 结点之间有分支,具有层次关系 是n个结点的有限集. 若n = 0,称为空树: 若n > 0,则它满足如下两个条件: 有且仅有一个特 ...

  6. 数据结构树、二叉树、完全二叉树、二叉查找树、平衡二叉树、红黑树、B+树

    树.二叉树.平衡二叉树.二叉搜索树 树的前序遍历.中序遍历和后序遍历 树的前序遍历.中序遍历和后续遍历是以遍历时根所在的位置顺序命名的.层次遍历即按层从上至下,从左至右遍历即可. 前序遍历:根-> ...

  7. 数据结构--树和二叉树

    文章目录 树和二叉树 树 1.树的定义 2.树的逻辑表示 3.树的基本术语: 4.树的性质 5.树的基本运算 二叉树 二叉树的存储结构 二叉树的遍历 树和二叉树 树 1.树的定义 2.树的逻辑表示 树 ...

  8. 数据结构——树与二叉树

    树与二叉树 一.树的定义: 1.定义:树(Tree)是n(n>=0)个节点的有限集,n=0时称为"空树".在任意一棵非空树中: ⒈有且仅有一个特定的称为根(root)的节点. ...

  9. Python数据结构与算法笔记(八):数据结构——树,二叉树和AVL树

    树 class Node:def __init__(self, name, type='dir'):self.name = nameself.type = type #"dir" ...

最新文章

  1. ajax实现关联词提示
  2. widedeep 在贝壳推荐场景的实践
  3. 【渝粤题库】国家开放大学2021春2320物流管理定量分析方法题目
  4. PHP+jquery 树状菜单
  5. 服务器显示配置命令,linux查看服务器配置命令
  6. Quanergy联手思科为智能交通创建物联网解决方案
  7. python使用默认参数
  8. activiti工作流 php,码云社 | 砺锋科技-SpringBoot整合Activiti工作流(附源码) - 用代码改变世界...
  9. python机器学习-乳腺癌细胞挖掘
  10. 限时,字节Java程序性能优化宝典大全,这才叫真正的性能优化
  11. 7.Excel数据分析-员工考勤表
  12. 即将首发 | 业界首个零售数字化创新白皮书,解锁全链路数字化致胜秘籍
  13. IARPA启动“奥丁”项目,发展生物特征识别技术
  14. 专家警告全球芯片短缺可能持续到 2022 年之后
  15. 浅谈到底什么是系统集成(弱电)和项目管理?
  16. 有时候内卷也可以走捷径,比如几行代码也可以霸榜朋友圈~
  17. 上半年要写的博客文章27
  18. 八位计算机最小二进制,八位二进制补码最小值
  19. 解题记录 LeetCode 下一个更大元素 II 单调栈
  20. 纳什均衡(Nash equilibrium)

热门文章

  1. 密码学——乘法密码实现
  2. 输入年份月份,得到该月月历
  3. 玲珑杯Round20
  4. 平稳随机过程通过线性系统
  5. 金蝶云星空对接打通精诚ERP应付单查询1接口与执行操作接口接口
  6. php采集程序的方法
  7. CorelDRAW 快捷键全攻略(1)
  8. php soapclient出错,PHP7 SoapClient问题
  9. PostgreSQL 生成列(Generated Columns)教程
  10. 智慧社区变革前夜:要么进化,要么淘汰