王道数据结构课后代码题 p149 第8—— 12(c语言代码实现)
目录
8.假设二叉树采用二叉链表存储结构存储,试设计一个算法,计算一棵给定二叉树的所有双分支结点个数。
9.设树B是一棵采用链式结构存储的二叉树,编写一个把树 B中所有结点的左、右子树进行交换的函数。
10.假设二叉树采用二叉链存储结构存储,设计一个算法,求先序遍历序列中第 k(1<=k<=二叉树中结点个数)个结点的值
11.已知二叉树以二叉链表存储,编写算法完成: 对于树中每个元素值为X 的结点,删去以它为根的子树,并释放相应的空间。
12.在二叉树中查找值为 x 的结点,试编写算法(用 C语言)打印值为x的结点的所有祖先,假设值为X的结点不多于一个。
8.假设二叉树采用二叉链表存储结构存储,试设计一个算法,计算一棵给定二叉树的所有双分支结点个数。
本题代码如下
int twonode(tree t)
{if (t == NULL)//若为空树return 0;else if (t->lchild&& t->rchild)//双分支结点return twonode(t->lchild) + twonode(t->rchild) + 1;else//单分支或叶子节点return twonode(t->lchild) + twonode(t->rchild);
}
完整测试代码
#include<stdio.h>
#include<stdlib.h>
#define true 1
#define false 0
typedef struct treenode
{char data;struct treenode* lchild, * rchild;
}treenode,*tree;
void buildtree(tree* t)
{char ch;ch = getchar();if (ch == '#')*t=NULL;else{*t = (treenode*)malloc(sizeof(treenode));(*t)->data = ch;buildtree(&((*t)->lchild));buildtree(&((*t)->rchild));}
}
int twonode(tree t)
{if (t == NULL)//若为空树return 0;else if (t->lchild&& t->rchild)//双分支结点return twonode(t->lchild) + twonode(t->rchild) + 1;else//单分支或叶子节点return twonode(t->lchild) + twonode(t->rchild);
}
int main()
{tree t;buildtree(&t);printf("双支数为%d\n",twonode(t));return 0;
}
用ABD##E##CF##G##这个测试

9.设树B是一棵采用链式结构存储的二叉树,编写一个把树 B中所有结点的左、右子树进行交换的函数。
本题代码如下
void swap(tree* t)
{if (*t){treenode* temp = (*t)->lchild;(*t)->lchild = (*t)->rchild;(*t)->rchild = temp;swap(&(*t)->lchild);swap(&(*t)->rchild);}
}
完整测试代码
#include<stdio.h>
#include<stdlib.h>
typedef struct treenode
{char data;struct treenode* lchild, * rchild;
}treenode,*tree;
void buildtree(tree* t)
{char ch;ch = getchar();if (ch =='#')*t = NULL;else{*t = (treenode*)malloc(sizeof(treenode));(*t)->data = ch;buildtree(&((*t)->lchild));buildtree(&((*t)->rchild));}
}
void swap(tree* t)
{if (*t){treenode* temp = (*t)->lchild;(*t)->lchild = (*t)->rchild;(*t)->rchild = temp;swap(&(*t)->lchild);swap(&(*t)->rchild);}
}
void disp(tree* t)
{if (*t){printf("%c", (*t)->data);disp(&(*t)->lchild);disp(&(*t)->rchild);}
}
int main()
{tree t;buildtree(&t);printf("交换过后的二叉树为(前序序列):");swap(&t);disp(&t);return 0;
}
用ABD##E##CF##G##测试

10.假设二叉树采用二叉链存储结构存储,设计一个算法,求先序遍历序列中第 k(1<=k<=二叉树中结点个数)个结点的值
本题代码如下
// 查找第k个节点值的函数
char serchk(tree* t, int k)
{if (*t == NULL) // 如果节点为空,返回'*'表示未找到return '*';if (i == k) // 如果当前节点是第k个节点,返回节点数据return (*t)->data;i++; // 更新当前节点位置char s = serchk(&(*t)->lchild, k); // 递归查找左子树中的第k个节点if (s != '*') // 如果左子树中找到,直接返回结果return s;s = serchk(&(*t)->rchild, k); // 否则递归查找右子树中的第k个节点return s; // 返回查找结果
}
完整测试代码
#include<stdio.h>// 定义二叉树节点结构体
typedef struct treenode
{char data; // 节点存储的数据struct treenode* lchild, * rchild; // 左右子节点指针
}treenode,*tree;// 构建二叉树函数
void buildtree(tree* t)
{char ch;ch = getchar(); // 从输入中读取一个字符if (ch == '#') // 如果字符为'#',表示空节点*t = NULL;else{*t = (treenode*)malloc(sizeof(treenode)); // 分配内存空间给新节点(*t)->data = ch; // 将读取到的字符赋值给节点数据(*t)->lchild = NULL; // 初始化左子节点为空(*t)->rchild = NULL; // 初始化右子节点为空buildtree(&(*t)->lchild); // 递归构建左子树buildtree(&(*t)->rchild); // 递归构建右子树}
}int i = 1; // 全局变量,用于记录当前遍历的节点位置// 查找第k个节点值的函数
char serchk(tree* t, int k)
{if (*t == NULL) // 如果节点为空,返回'*'表示未找到return '*';if (i == k) // 如果当前节点是第k个节点,返回节点数据return (*t)->data;i++; // 更新当前节点位置char s = serchk(&(*t)->lchild, k); // 递归查找左子树中的第k个节点if (s != '*') // 如果左子树中找到,直接返回结果return s;s = serchk(&(*t)->rchild, k); // 否则递归查找右子树中的第k个节点return s; // 返回查找结果
}int main()
{tree t; // 定义二叉树变量tbuildtree(&t); // 构建二叉树char f=serchk(&t, 5); // 查找第5个节点的值printf("%c", f); // 输出查找结果return 0;
}
用ABD##E##CF##G##测试

11.已知二叉树以二叉链表存储,编写算法完成: 对于树中每个元素值为X 的结点,删去以它为根的子树,并释放相应的空间。
可以直接使用前序遍历,访问到值为x的结点,就递归的删除它的左、右子树。
本题代码如下
void release(tree* t)//递归释放结点
{if (!*t)return;release(&(*t)->lchild);release(&(*t)->rchild);free(*t);
}
void deletex(tree* t,char x)
{if (*t == NULL)return;if((*t)->data==x){release(t);*t = NULL;}if (*t != NULL)//前序遍历的去找{deletex(&(*t)->lchild, x);deletex(&(*t)->rchild, x);}
}
完整测试代码
#include<stdio.h>
#include<stdlib.h>
typedef struct treenode
{char data;struct treenode* lchild, * rchild;
}treenode,*tree;
void buildtree(tree* t)
{char ch;ch = getchar();if (ch == '#')*t = NULL;else{*t = (treenode*)malloc(sizeof(treenode));(*t)->data = ch;buildtree(&(*t)->lchild);buildtree(&(*t)->rchild);}
}
void release(tree* t)
{if (!*t)return;release(&(*t)->lchild);release(&(*t)->rchild);free(*t);
}
void deletex(tree* t,char x)
{if (*t == NULL)return;if((*t)->data==x){release(t);*t = NULL;}if (*t != NULL){deletex(&(*t)->lchild, x);deletex(&(*t)->rchild, x);}
}
void disp(tree* t)
{if (*t){printf("%c", (*t)->data);disp(&(*t)->lchild);disp(&(*t)->rchild);}
}
int main()
{tree t;buildtree(&t);deletex(&t, 'C');disp(&t);return 0;
}
用ABD##E##CF##G##测试
/* A
B C
D E F G */

12.在二叉树中查找值为 x 的结点,试编写算法(用 C语言)打印值为x的结点的所有祖先,假设值为X的结点不多于一个。
采用非递归后序遍历,最后访问根结点,访问到值为 x 的结点时,栈中所有元素均为该结点的祖先,依次出栈打印.
本题代码如下(注释详解)
// 寻找指定字符的所有祖先结点
void ancestor(tree* t, char x)
{stack s[10]; // 定义一个大小为10的栈,用于存储二叉树的结点指针和标记位 int top = -1; // 初始化栈顶为-1,表示栈为空 while (*t != NULL || top != -1) // 当当前节点非空或者栈非空时,继续循环 {while (*t != NULL) // 当当前结点非空时,将其入栈并向左子树遍历 {top++;s[top].t = *t; // 将当前结点入栈 s[top].tag = 0; // 标记位设为0,表示该结点尚未被访问过 *t = (*t)->lchild; // 向左子树遍历 }while (top != -1 && s[top].tag == 1) // 当栈非空且栈顶元素的标记位为1时,出栈(即回退) {top--;}if (top != -1) // 当栈非空时,进行以下操作 {if (s[top].t->data == x) // 如果栈顶元素的data字段等于指定字符x,则输出所有祖先结点 {printf("所有的祖先结点为:\n");for (int i = 0; i < top; i++) // 遍历栈中所有元素(不包括栈顶元素)并输出其data字段 {printf("%c ", s[i].t->data);}break; // 找到指定字符的所有祖先结点后,跳出循环 }s[top].tag = 1; // 如果栈顶元素的data字段不等于指定字符x,将其标记位设为1,表示该结点已经被访问过 *t = s[top].t->rchild; // 向右子树遍历 }}
}
完整测试代码
#include<stdio.h>
#include<stdlib.h>
// 定义一个二叉树结点
typedef struct treenode
{char data; //结点存储的数据 struct treenode* lchild, * rchild; // 结点的左右孩子
} treenode, * tree;
// 定义一个栈结构
typedef struct
{treenode* t; // 栈中存储的是二叉树的结点指针 int tag; // 标记位,主要用于记录结点是否已经被访问过
} stack;
// 建立二叉树
void buildtree(tree* t)
{char ch;ch = getchar(); // 从标准输入获取一个字符 if (ch == '#') // 如果输入的是'#',则该节点为空 *t = NULL;else{*t = (treenode*)malloc(sizeof(treenode)); // 为新的结点分配内存空间 (*t)->data = ch; // 将输入的字符赋值给节点的data字段 (*t)->lchild = NULL; // 初始化结点的左右孩子为空 (*t)->rchild = NULL;buildtree(&(*t)->lchild); // 递归建立左子树 buildtree(&(*t)->rchild); // 递归建立右子树 }
}
// 寻找指定字符的所有祖先结点
void ancestor(tree* t, char x)
{stack s[10]; // 定义一个大小为10的栈,用于存储二叉树的结点指针和标记位 int top = -1; // 初始化栈顶为-1,表示栈为空 while (*t != NULL || top != -1) // 当当前节点非空或者栈非空时,继续循环 {while (*t != NULL) // 当当前结点非空时,将其入栈并向左子树遍历 {top++;s[top].t = *t; // 将当前结点入栈 s[top].tag = 0; // 标记位设为0,表示该结点尚未被访问过 *t = (*t)->lchild; // 向左子树遍历 }while (top != -1 && s[top].tag == 1) // 当栈非空且栈顶元素的标记位为1时,出栈(即回退) {top--;}if (top != -1) // 当栈非空时,进行以下操作 {if (s[top].t->data == x) // 如果栈顶元素的data字段等于指定字符x,则输出所有祖先结点 {printf("所有的祖先结点为:\n");for (int i = 0; i < top; i++) // 遍历栈中所有元素(不包括栈顶元素)并输出其data字段 {printf("%c ", s[i].t->data);}break; // 找到指定字符的所有祖先结点后,跳出循环 }s[top].tag = 1; // 如果栈顶元素的data字段不等于指定字符x,将其标记位设为1,表示该结点已经被访问过 *t = s[top].t->rchild; // 向右子树遍历 }}
}
int main()
{tree t; // 定义一个二叉树节点指针t buildtree(&t); // 建立二叉树 ancestor(&t, 'D'); // 找出字符'D'的所有祖先结点并输出 return 0;
}
用ABD##E##CF##G##测试
/* A
B C
D E F G */

相关文章:
王道数据结构课后代码题 p149 第8—— 12(c语言代码实现)
目录 8.假设二叉树采用二叉链表存储结构存储,试设计一个算法,计算一棵给定二叉树的所有双分支结点个数。 9.设树B是一棵采用链式结构存储的二叉树,编写一个把树 B中所有结点的左、右子树进行交换的函数。 10.假设二叉树采用二叉链存储结构存储…...
Nginx服务优化以及防盗链
1. 隐藏版本号 以在 CentOS 中使用命令 curl -I http://192.168.66.10 显示响应报文首部信息。 查看版本号 curl -I http://192.168.66.10 1. 修改配置文件 vim /usr/local/nginx/conf/nginx.conf http {include mime.types;default_type application/octet-stream;…...
20231210 随机矩阵和M矩阵
1. 非负矩阵:矩阵元素均非负 定义 7.1.1 设 A ( a i j ) ∈ R m n \boldsymbol{A}\left(a_{i j}\right) \in \mathbb{R}^{m \times n} A(aij)∈Rmn, 如果 a i j ⩾ 0 , i 1 , ⋯ , m ; j 1 , ⋯ , n , a_{i j} \geqslant 0, \quad i1, \cdots, m ; j1, \cd…...
Linux(centos)学习笔记(初学)
[rootlocalhost~]#:[用户名主机名 当前所在目录]#超级管理员标识 $普通用户的标识 Ctrlshift放大终端字体 Ctrl缩小终端字体 Tab可以补全命令 Ctrlshiftc/V复制粘贴 / :根目录,Linux系统起点 ls: #list列出目录的内容,通常用户查看…...
ECharts标题字体大小自适应变化
我们在做自适应Echarts的时候,字体大小在配置项里是如下配置的, title 标题组件,包含主标题和副标题。 以下是常用的对标题的设置: title:{//设置图表的标题text:"主标题",link:"baidu.com", //设置标题超链接target:"self",...
解决使用pnpm安装时Sharp模块报错的方法
在使用pnpm进行项目依赖安装的过程中,有时候会遇到Sharp模块报错的情况。Sharp是一个用于处理图像的Node.js模块,但它的安装可能会因为各种原因而失败,导致项目无法正常启动。本文将介绍这个问题的方法。 问题描述 解决方法 在命令行分别输…...
Redis 数据的持久化 RDB、AOF、RDB + AOF、No persistence 各自优缺点
文章目录 一、RDB (Redis Database)1.1 RDB 优势1.2 RDB 缺点1.3 RDB 如何工作1.4 RDB配置1.5 开启/关闭,RDB快照策略,save指令1.6 持久化硬盘文件,dbfilename指令1.7 持久化硬盘文件的存储地址,dir指令 二、AOF (Append Only Fil…...
回味童年经典游戏的项目
目录 1.超级玛丽2.坦克大战3.吃豆人游戏4.贪吃蛇游戏 1.超级玛丽 项目地址:超级马里奥游戏源码 在线试玩网址在资源描述中 在线试玩:http://martindrapeau.github.io/backbone-game-engine/super-mario-bros/index.html 主要语言:JavaScript…...
Electron[5] 渲染进程和主进程
1 进程 Electron里头的进程分为渲染进程和主进程。简单理解: main.js就是主进程每个页面就是渲染进程一个Electron应用仅有一个主进程,可以有多个渲染进程 上面的这些概念很重要,不展开细讲。 2 进程职责 主进程是用来实现应用的基础功能…...
基于Java SSM框架实现大学生校园兼职系统项目【项目源码+论文说明】
基于java的SSM框架实现大学生兼职系统演示 摘要 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,大学生校园兼职系统当然也不能排除在外。大学生校园兼职系统是以实际运用为开…...
Codeforces Round 913 (Div. 3) A~E
目录 A. Rook 问题分析: B. YetnotherrokenKeoard 问题分析: C. Removal of Unattractive Pairs 问题分析: D. Jumping Through Segments 问题分析: E. Good Triples 问题分析: A. Rook 问题分析: 给一个棋子将其同行同列的位置输出 #include<bits/s…...
反序列化 [网鼎杯 2020 朱雀组]phpweb 1
打开题目 我们发现这个页面一直在不断的刷新 我们bp抓包一下看看 我们发现index.php用post方式传了两个参数上去,func和p 我们需要猜测func和p两个参数之间的关系,可以用php函数MD5测一下看看 我们在响应处得到了一串密文,md5解密一下看看 发…...
Java 何时会触发一个类的初始化
Java 何时会触发一个类的初始化? 使用new关键字创建对象访问类的静态成员变量 或 对类的静态成员变量进行赋值调用类的静态方法反射调用类时,如 Class.forName()初始化子类时,会先初始化其父类(如果父类还没有进行过初始化的话&a…...
我的记事本
url uniform resource locator. 统一资源定位符 请求状态码 1XX:信息响应 2XX:成功响应 3XX:重定向消息 4XX:客户端错误响应 5XX:服务器端错误响应 IP地址分类 本机回环IP地址:127.0.0.1 ~ 127.255.255.254 局域网IP(私网IP) 192.168.0.0 &am…...
GO设计模式——4、单例模式(创建型)
目录 单例模式(Singleton Pattern) 优缺点 使用场景 饿汉式和懒汉式单例模式 单例模式(Singleton Pattern) 单例模式(Singleton Pattern)是一个类只允许创建一个对象(或者实例ÿ…...
我对迁移学习的一点理解——领域适应(系列3)
文章目录 1. 领域适应(Domain Adaptation)的基本概念2.领域适应(Domain Adaptation)的目标3.领域适应(Domain Adaptation)的实现方法4.领域适应(Domain Adaptation)的可以解决的问题…...
【openssl】RSA 生成公钥私钥 |通过私钥获取公钥
通过博客:Window系统如何编译openssl 编译出openssl.exe(位于apps文件夹下)。 现在需要使用它获得公钥私钥、通过私钥获取公钥 目录 说明!!! 一.定位openssl.exe目录 二、进入命令cmd 三、生成私钥 …...
MongoDB的删除文档、查询文档语句
本文主要介绍MongoDB的删除文档、查询文档命令语句。 目录 MongoDB删除文档MongoDB查询文档 MongoDB删除文档 MongoDB是一种基于文档的NoSQL数据库,它使用BSON格式存储文档。删除文档是MongoDB数据库中的常见操作之一。 下面是MongoDB删除文档的详细介绍和示例&am…...
Rust编程语言入门教程(三)-trait
文章目录 Rust编程语言入门教程(三)-trait什么是 trait?trait使用举例 Rust编程语言入门教程(三)-trait 什么是 trait? trait 是 Rust 中的接口,它定义了类型使用这个接口的行为。你可以类比到…...
LeetCode-1566. 重复至少 K 次且长度为 M 的模式【数组 枚举】
LeetCode-1566. 重复至少 K 次且长度为 M 的模式【数组 枚举】 题目描述:解题思路一:题意就是找出长度为m且连续重复k次的子数组。解题思路就是暴力枚举加剪枝。解题思路二:思路差不多解题思路三:0 题目描述: 给你一个…...
AXI总线协议实战:手把手教你用Verilog模拟关键信号波形(附代码)
AXI总线协议实战:手把手教你用Verilog模拟关键信号波形(附代码) 在FPGA和数字电路设计中,AXI总线协议已经成为事实上的标准接口。作为AMBA协议家族中最重要的一员,AXI协议以其高性能、高带宽和灵活性著称。但对于初学者…...
Phi-4-Reasoning-Vision镜像使用指南:双卡负载均衡与CUDA内存优化技巧
Phi-4-Reasoning-Vision镜像使用指南:双卡负载均衡与CUDA内存优化技巧 1. 工具概述 Phi-4-Reasoning-Vision是基于微软Phi-4-reasoning-vision-15B多模态大模型开发的高性能推理工具,专为双卡4090环境优化设计。这个工具能够充分发挥15B大模型的深度推…...
基于YOLOv5和swin-Unet的带钢缺陷智能识别系统
十一、基于YOLOv5和swin-Unet的带钢缺陷智能识别系统 1.带标签数据集,包括检测和分割数据集,其中检测数据共计6类,1800张图片。 2.含模型训练权重。 3.pyqt5设计的界面,带登录界面,注册界面和运行界面。 4.提供详细的环…...
BilibiliDown:基于Java的B站视频下载技术方案与实现解析
BilibiliDown:基于Java的B站视频下载技术方案与实现解析 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors…...
【微信小程序更新机制全解析】原理、实践与最佳实践
前言 微信小程序的更新机制,是连接开发者版本迭代与用户体验的核心桥梁。它设计的核心逻辑是**“自动无感更新为主,手动强制更新为辅”,在保证小程序快速启动、稳定可用**的前提下,尽可能让用户使用最新版本;同时为开…...
深度学习模型过拟合的实战诊断与优化策略
1. 过拟合现象的诊断方法 第一次训练神经网络时,我盯着训练准确率冲到99%兴奋不已,结果测试集表现只有65%——这就是典型的过拟合现场。判断模型是否过拟合,就像医生看体检报告,需要多维度交叉验证。 最直观的方法是训练集与验证集…...
ASLR:现代操作系统中的内存安全守护者
1. ASLR:现代操作系统的内存安全基石 想象一下你家的门锁每天都会自动更换位置——这就是ASLR(地址空间布局随机化)对计算机程序做的事。作为现代操作系统最基本的安全机制之一,ASLR通过打乱程序在内存中的"居住地址"&…...
别再只用CEEMDAN了!信号分解后,这7种熵指标到底该怎么选?(能量熵/近似熵/模糊熵对比)
信号分解后熵指标选型指南:从能量熵到多尺度排列熵的深度解析 在信号处理领域,CEEMDAN等分解方法早已成为研究人员的标准工具包——它们像精密的滤波器,将复杂信号拆解为一系列物理意义明确的IMF分量。但当我们面对这些分解后的子信号时&…...
CVE-2016-2183漏洞自查与修复指南:你的Nginx/Apache还在用有问题的SSL/TLS协议吗?
CVE-2016-2183漏洞深度解析与实战修复:从检测到防护的全链路方案 凌晨三点,运维团队的告警系统突然响起——安全扫描报告显示生产环境存在SSL/TLS协议信息泄露风险。这不是普通的漏洞警报,而是可能直接导致加密通信被破解的CVE-2016-2183。作…...
Phi-3-mini-4k-instruct-gguf快速部署:7860端口网页服务+独立venv隔离环境实录
Phi-3-mini-4k-instruct-gguf快速部署:7860端口网页服务独立venv隔离环境实录 1. 模型简介 Phi-3-mini-4k-instruct-gguf 是微软 Phi-3 系列中的轻量级文本生成模型 GGUF 版本。这个模型特别适合以下场景: 智能问答文本改写与润色内容摘要生成简短创意…...
