当前位置: 首页 > news >正文

王道数据结构课后代码题 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.假设二叉树采用二叉链表存储结构存储&#xff0c;试设计一个算法&#xff0c;计算一棵给定二叉树的所有双分支结点个数。 9.设树B是一棵采用链式结构存储的二叉树&#xff0c;编写一个把树 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. 非负矩阵&#xff1a;矩阵元素均非负 定义 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复制粘贴 / &#xff1a;根目录&#xff0c;Linux系统起点 ls&#xff1a; #list列出目录的内容&#xff0c;通常用户查看…...

ECharts标题字体大小自适应变化

我们在做自适应Echarts的时候,字体大小在配置项里是如下配置的, title 标题组件,包含主标题和副标题。 以下是常用的对标题的设置: title:{//设置图表的标题text:"主标题",link:"baidu.com", //设置标题超链接target:"self",...

解决使用pnpm安装时Sharp模块报错的方法

在使用pnpm进行项目依赖安装的过程中&#xff0c;有时候会遇到Sharp模块报错的情况。Sharp是一个用于处理图像的Node.js模块&#xff0c;但它的安装可能会因为各种原因而失败&#xff0c;导致项目无法正常启动。本文将介绍这个问题的方法。 问题描述 解决方法 在命令行分别输…...

Redis 数据的持久化 RDB、AOF、RDB + AOF、No persistence 各自优缺点

文章目录 一、RDB (Redis Database)1.1 RDB 优势1.2 RDB 缺点1.3 RDB 如何工作1.4 RDB配置1.5 开启/关闭&#xff0c;RDB快照策略&#xff0c;save指令1.6 持久化硬盘文件&#xff0c;dbfilename指令1.7 持久化硬盘文件的存储地址&#xff0c;dir指令 二、AOF (Append Only Fil…...

回味童年经典游戏的项目

目录 1.超级玛丽2.坦克大战3.吃豆人游戏4.贪吃蛇游戏 1.超级玛丽 项目地址&#xff1a;超级马里奥游戏源码 在线试玩网址在资源描述中 在线试玩&#xff1a;http://martindrapeau.github.io/backbone-game-engine/super-mario-bros/index.html 主要语言&#xff1a;JavaScript…...

Electron[5] 渲染进程和主进程

1 进程 Electron里头的进程分为渲染进程和主进程。简单理解&#xff1a; main.js就是主进程每个页面就是渲染进程一个Electron应用仅有一个主进程&#xff0c;可以有多个渲染进程 上面的这些概念很重要&#xff0c;不展开细讲。 2 进程职责 主进程是用来实现应用的基础功能…...

基于Java SSM框架实现大学生校园兼职系统项目【项目源码+论文说明】

基于java的SSM框架实现大学生兼职系统演示 摘要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;大学生校园兼职系统当然也不能排除在外。大学生校园兼职系统是以实际运用为开…...

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方式传了两个参数上去&#xff0c;func和p 我们需要猜测func和p两个参数之间的关系&#xff0c;可以用php函数MD5测一下看看 我们在响应处得到了一串密文&#xff0c;md5解密一下看看 发…...

Java 何时会触发一个类的初始化

Java 何时会触发一个类的初始化&#xff1f; 使用new关键字创建对象访问类的静态成员变量 或 对类的静态成员变量进行赋值调用类的静态方法反射调用类时&#xff0c;如 Class.forName()初始化子类时&#xff0c;会先初始化其父类&#xff08;如果父类还没有进行过初始化的话&a…...

我的记事本

url uniform resource locator. 统一资源定位符 请求状态码 1XX:信息响应 2XX:成功响应 3XX:重定向消息 4XX:客户端错误响应 5XX:服务器端错误响应 IP地址分类 本机回环IP地址&#xff1a;127.0.0.1 &#xff5e; 127.255.255.254 局域网IP(私网IP) 192.168.0.0 &am…...

GO设计模式——4、单例模式(创建型)

目录 单例模式&#xff08;Singleton Pattern&#xff09; 优缺点 使用场景 饿汉式和懒汉式单例模式 单例模式&#xff08;Singleton Pattern&#xff09; 单例模式&#xff08;Singleton Pattern&#xff09;是一个类只允许创建一个对象&#xff08;或者实例&#xff…...

我对迁移学习的一点理解——领域适应(系列3)

文章目录 1. 领域适应&#xff08;Domain Adaptation&#xff09;的基本概念2.领域适应&#xff08;Domain Adaptation&#xff09;的目标3.领域适应&#xff08;Domain Adaptation&#xff09;的实现方法4.领域适应&#xff08;Domain Adaptation&#xff09;的可以解决的问题…...

【openssl】RSA 生成公钥私钥 |通过私钥获取公钥

通过博客&#xff1a;Window系统如何编译openssl 编译出openssl.exe&#xff08;位于apps文件夹下&#xff09;。 现在需要使用它获得公钥私钥、通过私钥获取公钥 目录 说明&#xff01;&#xff01;&#xff01; 一.定位openssl.exe目录 二、进入命令cmd 三、生成私钥 …...

MongoDB的删除文档、查询文档语句

本文主要介绍MongoDB的删除文档、查询文档命令语句。 目录 MongoDB删除文档MongoDB查询文档 MongoDB删除文档 MongoDB是一种基于文档的NoSQL数据库&#xff0c;它使用BSON格式存储文档。删除文档是MongoDB数据库中的常见操作之一。 下面是MongoDB删除文档的详细介绍和示例&am…...

Rust编程语言入门教程(三)-trait

文章目录 Rust编程语言入门教程&#xff08;三&#xff09;-trait什么是 trait&#xff1f;trait使用举例 Rust编程语言入门教程&#xff08;三&#xff09;-trait 什么是 trait&#xff1f; trait 是 Rust 中的接口&#xff0c;它定义了类型使用这个接口的行为。你可以类比到…...

LeetCode-1566. 重复至少 K 次且长度为 M 的模式【数组 枚举】

LeetCode-1566. 重复至少 K 次且长度为 M 的模式【数组 枚举】 题目描述&#xff1a;解题思路一&#xff1a;题意就是找出长度为m且连续重复k次的子数组。解题思路就是暴力枚举加剪枝。解题思路二&#xff1a;思路差不多解题思路三&#xff1a;0 题目描述&#xff1a; 给你一个…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...