当前位置: 首页 > 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; 给你一个…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...

【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)

旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据&#xff01;该数据集源自2025年4月发表于《地理学报》的论文成果…...

医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor

1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...

android计算器代码

本次作业要求实现一个计算器应用的基础框架。以下是布局文件的核心代码&#xff1a; <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"andr…...