数据结构例程——以孩子兄弟链存储的树的高度

本文是数据结构基础系列(6):树和二叉树第5课时树的存储结构的例程。

例: 以孩子-兄弟链作为存储结构,求树的高度
这里写图片描述

源程序:【说明——函数TreeCreate仅创建了如上图所示的图,不具有通用性。】

#include <stdio.h>
#include <malloc.h>

typedef char ElemType;
typedef struct tnode
{
    ElemType data;  //节点的值
    struct tnode *hp;   //指向兄弟
    struct tnode *vp;   //指向孩子节点
} TSBNode;
int TreeHeight(TSBNode *t);
void TreeCreate(TSBNode *&t);
void TreeDisp(TSBNode *t);

int TreeHeight(TSBNode *t)
{
    TSBNode *p;
    int m, max = 0;
    if(t==NULL)
        return(0);
    else if(t->vp==NULL)
        return(1);
    else
    {
        //求t的子树的最大高度max
        p=t->vp;
        while(p!=NULL)
        {
            m=TreeHeight(p);
            if(max<m)
                max=m;
            p=p->hp;
        }
        return(max+1);
    }
}

int main()
{
    TSBNode *tree;
    TreeCreate(tree);
    printf("Height: %d\n", TreeHeight(tree));
    TreeDisp(tree);
    return 0;
}

void TreeCreate(TSBNode *&t)
{
    //本例仅建造说明中特定的树,以支持演示
    TSBNode *a, *b, *c, *d, *e, *f, *g;
    a = (TSBNode *)malloc(sizeof(TSBNode));
    b = (TSBNode *)malloc(sizeof(TSBNode));
    c = (TSBNode *)malloc(sizeof(TSBNode));
    d = (TSBNode *)malloc(sizeof(TSBNode));
    e = (TSBNode *)malloc(sizeof(TSBNode));
    f = (TSBNode *)malloc(sizeof(TSBNode));
    g = (TSBNode *)malloc(sizeof(TSBNode));
    a->data = 'a';
    b->data = 'b';
    c->data = 'c';
    d->data = 'd';
    e->data = 'e';
    f->data = 'f';
    g->data = 'g';
    a->vp = b;
    a->hp = NULL;
    b->vp = d;
    b->hp = c;
    c->vp = NULL;
    c->hp = NULL;
    d->vp = NULL;
    d->hp = e;
    e->vp = g;
    e->hp = f;
    f->vp = NULL;
    f->hp = NULL;
    g->vp = NULL;
    g->hp = NULL;
    t=a;  //a作为根
    return;
}

void TreeDisp(TSBNode *t)
{
    if(t!=NULL)
    {
        printf("node value: %c\n", t->data);
        printf("%c\'s first child --> ", t->data);
        TreeDisp(t->hp);
        printf("%c\'s brother(its father\'s another child) --> ", t->data);
        TreeDisp(t->vp);
    }
    else
    {
        printf("NULL\n");
    }
}
  • 13
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
易语言简易线程池的实现 ——V雪落有声V原创 转载请保留 前文: 为了能充分理解本篇文章的内容,需要了解的知识如下: 1.事件对象的使用:http://baike.baidu.com/view/751499.htm 2.信号量的使用:http://baike.baidu.com/view/1285861.htm 3.等待单一对象,等待多个对象的使用:http://baike.baidu.com/view/1424795.htm,http://baike.baidu.com/view/908866.htm 4.表,队列——易语言数据结构支持库的使用:见易语言帮助文档 5.多线程间的许可证的使用:见易语言帮助文档 6.原子锁操作:http://baike.baidu.com/view/6235756.htm 一.了解线程池的运行原理: 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。 具体参见:http://baike.baidu.com/view/262150.htm 二.实现的过程概述: 1.通过一个主线程来监视是否有新任务,如果有新任务,则判断当前的线程数是否大于最大线程数,如果小于最大线程数则创建新线程,反之则加入线程队列等待执行。 2.当时间经过过长(1分钟,可手动设置)主线程会自动关闭一部分的线程,保留最小线程数,来释放资源。 3.执行任务的线程等待队列,如果队列中有任务,则执行任务,如果队列中没有任务,则进入内核等待状态,当队列中有任务时继续执行。而不是重复性创建和销毁线程。 具体请看上图。 三.线程句柄的管理 每次新建线程时,将自动将内部的_ID增加1,保存到“类_线程句柄数组管理”中,该类以存储的方式,保存所有的线程句柄和ID。当销毁线程池或关闭子线程时时,关闭所有或对应的句柄。 四.任务队列的实现 任务队列采用易语言中的“数据结构支持库”中的“队列”,队列为:先进先出,这样保证是按照先后顺序来进行的,而且弹出后会自动在队列中删除,使用方便。在有新任务时,由主线程将任务信息压入队列,并且设置“内部_线程池数据.__监视任务队列信号量”的计数值+1,子线程通过监听这个事件,从队列中弹出获取一个信息,然后进行执行。 五.销毁的实现 当执行销毁线程池的命令时,设置“__线程池退出事件信号量”为有信号,使主线程退出循环并执行清理代码,设置“__子线程结束信号量”计数值为最大(虽然不用这么大),保证每个线程都退出。而后主线程监视所有的子线程退出,如果超过“超时时间”则强制销毁所有子线程,并且释放其他资源,返回。 监视方法:主线程监视:“子线程退出完毕事件”事件,子线程每次退出都会递减:“内部_线程池数据.__运行子线程数”的值,如果“内部_线程池数据.__运行子线程数”=0,则会设置“子线程退出完毕事件”为有信号,表示所有子线程都退出了,然后执行清理工作。
因文件超过20M不能上传,所以拆分为两个文件分次上传 第1章 COM背景知识 1.1 COM的起源 1.1.1 软件业面临的挑战 1.1.2 传统解决方案 1.1.3 面向对象程序设计方法 1.1.4 最终解决方案:组件软件 1.1.5 面向对象的组件模型——COM 1.2 COM的发展历程 1.2.1 COM以前的对象技术:DDE、OLE 1、VBX控件 1.2.2 COM首次亮相:OLE2 1.2.3 Microsoft拥抱Internet:ActiveX 1.2.4 更多的新名词:Windows DNA和COM+ 1.2.5 远程对象:ORBs和DCOM 1.2.6 COM的最新版本:COM+ 1.3 COM技术现状 1.3.1 COM与CORBA 1.3.2 COM与Enterprise Java Beans 1.3.3 Windows之外的COM 小结 第2章 从C++到COM 2.1 C++客户重用C++对象——例程DB 2.1.1 C++对象 2.1.2 客户程序 2.2 将C++对象移进DLL中——例程DB_cppdll 2.2.1 成员函数的引出 2.2.2 内存分配 2.2.3 Unicode/ASCII兼容 2.2.4 例程实现 2.2.4.1 修改接口文件 2.2.4.2 修改对象程序 2.2.4.3 修改客户程序 2.3 C++对象使用抽象基类——例程DB_vtbl 2.3.1 问题:私有数据成员被暴露 2.3.2 解决方案:抽象基类 2.3.2.1 什么是抽象基类(Abstract Base Class) 2.3.2.2 实现秘诀:虚函数(Virtual Functions) 2.3.3 使用抽象基类 2.3.4 例程实现 2.3.4.1 修改接口文件 2.3.4.2 修改对象程序 2.3.4.3 修改客户程序 2.4 改由COM库装载C++对象——例程dbalmostcom 2.4.1 COM库 2.4.2 对象创建的标准入口点 2.4.3 标准对象创建API 2.4.4 标准对象注册 2.4.5 例程实现 2.4.5.1 修改接口文件 2.4.5.2 修改对象程序 2.4.5.3 修改客户程序 2.5 将C++对象变成COM对象 2.5.1 引用计数 2.5.2 多接口 2.5.3 IUnknown接口 2.5.4 标准类厂接口:IClassFactory 2.5.5 对象代码的动态卸载 2.5.6 自动注册 2.5.7 例程实现 2.5.7.1 修改接口文件 2.5.7.2 修改对象程序 2.5.7.3 修改客户程序 2.6 为COM对象添加多接口支持 2.6.1 多接口 2.6.2 DEFINE_GUID 2.6.3 例程实现 2.6.3.1 修改接口文件 2.6.3.2 修改对象程序 2.6.3.3 修改客户程序 小结 第3章 COM基础知识 3.1 对象与接口 3.1.1 COM对象 3.1.2 COM接口 3.1.3 IUnknown接口 3.1.3.1 生存期控制:AddRef和Release 3.1.3.2 接口查询:QueryInterface 3.1.4 全球唯一标识符GUID 3.1.5 COM接口定义 3.1.6 接口描述语言IDL 3.2 COM应用模型 3.2.1 客户/服务器模型 3.2.2 进程内组件 3.2.3 进程外组件 3.2.4 COM库 3.2.5 HRESULT返回值 3.2.6 COM与注册表 3.3 COM组件 3.3.1 实现类厂对象 3.3.2 类厂对象的创建 3.3.3 实现自动注册 3.3.4 实现自动卸载 3.4 COM客户 3.4.1 COM对象创建函数 3.4.1.1 CoGetClassObject 3.4.1.2 CoCreateInstance 3.4.1.3 CoCreateInstanceEx 3.4.2 如何调用进程内组件 3.4.3 COM客户调用进程外组件 3.5 进一步认识COM 3.5.1 可重用机制:包容和聚合 3.5.2 进程透明性 3.5.3 安全性机制 小结 第4章 COM扩展技术 4.1 可连接对象机制 4.1.1 客户、接收器与可连接对象 4.1.1.1 接收器 4.1.1.2 可连接对象 4.1.1.3 客户 4.1.2 实现可连接对象 4.1.3 实现接收器 4.1.4 建立接收器与连接点的连接 4.1.5 获得出接口的类型信息 4.2 结构化存储 4.2.1 什么叫结构化存储和复合文件 4.2.2 存储对象和IStorage接口 4.2.2.1 IStorage接口 4.2.2.2 获得IStorage指针 4.2.2.3 释放STATSTG内存 4.2.2.4 枚举存储对象中的元
http://www.400gb.com/u/256394 译者序 前言 致谢 第1章 绪论  1.1 评估算法  1.2 修改算法   1.2.1 主要的优化:I/O   1.2.2 主要的优化:函数调用  1.3 资源和参考资料 第2章 基本数据结构  2.1 表   2.1.1 双向表   2.1.2 表的其他特征  2.2 栈和队列   2.2.1 栈的特征   2.2.2 队列的特征 第3章 散列  3.1 散列的概念  3.2 散列函数  3.3 冲突解决方法   3.3.1 线性再散列法   3.3.2 非线性再散列法   3.3.3 外部拉法  3.4 性能问题  3.5 资源和参考资料 第4章 查找  4.1 查找的特征   4.1.1 准备时间   4.1.2 运行时间     4.1.3 回溯的需要  4.2 蛮力查找  4.3 Boyer Moore查找   4.3.1 启发式方法#1:跳过字符   4.3.2 启发式方法#2:重复模式  4.4 多字符串查找  4.5 用于正则表达式的字符串查找:grep  4.6 近似字符串匹配技术  4.7 语音比较:Soundex算法  4.8 Metaphone:现代的Soundex  4.9 选择技术  4.10 资源和参考资料   4.10.1 通用参考资料   4.10.2 Boyer Moore   4.10.3 多字符串查找   4.10.4 正则表达式查找   4.10.5 近似字符串匹配   4.10.6 Soundex算法和Metaphone算法 第5章 排序  5.1 排序的基本特征   5.1.1 稳定性   5.1.2 对哨兵的需求   5.1.3 对表进行排序的能力   5.1.4 输入的阶的相关性   5.1.5 对额外存储空间的需求   5.1.6 内部排序技术与外部排序技术  5.2 排序模型   5.2.1 冒泡排序   5.2.2 插入排序   5.2.3 希尔排序   5.2.4 快速排序   5.2.5 堆排序  5.3 对表进行插入排序  5.4 对表进行快速排序  5.5 对多个键进行排序——不稳定排序的修正方法  5.6 网络排序  5.7 小结:选择一种排序算法  5.8 资源和参考资料 第6章   6.1 二叉   6.1.1 查找   6.1.2 节点插入   6.1.3 节点删除   6.1.4 二叉查找的性能   6.1.5 AVL  6.2 红黑  6.3 伸展  6.4 B   6.4.1 保持B平衡   6.4.2 实现B算法   6.4.3 B实现的代码  6.5 可以看见森林吗  6.6 资源和参考资料 第7章 日期和时间  7.1 日期例程的库  7.2 时间例程  7.3 用于日期和时间数据的格式  7.4 最后的提醒  7.5 资源和参考资料 第8章 任意精度的算术  8.1 构建计算器8.2表示数字  8.3 计算  8.4 加法  8.5 减法  8.6 乘法  8.7 除法  8.8 关于计算器要注意的最后几点  8.9 用于计算平方根的牛顿算法  8.10 分期付款表  8.11 资源和参考资料 第9章 数据压缩  9.1 行程编码  9.2 霍夫曼压缩   9.2.1 代码   9.2.2 其他问题  9.3 滑动窗口压缩  9.4 基于字典的压缩(LZW)   9.4.1 LZW算法的伪代码   9.4.2 LZW压缩的实现   9.4.3 填满字典  9.5 使用哪种压缩方法  9.6 资源和参考资料 第10章 数据完整性和验证  10.1 简单的校验和  10.2 加权校验和  10.3 循环冗余校验   10.3.1 CRC CCITT   10.3.2 CRC 16   10.3.3 CRC 32   10.4 资源和参考资料
内容简介 《接器和加载器》讲述构建程序的关键工具——接器和加载器,内容包括接和加载、体系结构、目标文件、存储分配、符号管理、库、重定位、加载和覆盖、共享库、动态接和加载、动态接的共享库,以及着眼于成熟的现代接器所做的一些变化;并介绍一个持续的实践项目,即使用Perl语言开发一个可用的小接器。 《接器和加载器》适合高校计算机相关专业的学生、实习程序员、语言设计者和开发人员阅读参考。 编辑推荐 《接器和加载器》:不管你的编程语言是什么,不管你的平台是什么,你很可能总是会涉及接器和加载器的功能。但是你知道如何最大限度地利用它们吗?只有现在,随着《接器和加载器》的出版,总算有一本深入完整地彻底揭示编译时和运行时过程的权威著作了。 《接器和加载器》首先通过实例深入浅出地阐述了在不同的编译器和操作系统中接和加载过程的差异。在这个基础上,作者提出了清晰实用的忠告,来帮助你创建更快、更清晰的代码。你将会学习如何规避和Windows DLL相关的陷阱,充分利用UNIX ELF库模式等。如果你对程序设计抱有非常认真的态度,那么你可以通过这本书充分地理解这个领域内最难懂的主题之一。《接器和加载器》对于编译器和操作系统课程同样也是一本理想的补充读物。 《接器和加载器》特性 ◆覆盖了Windows,UNIX,Linux,BeOS和其它操作系统的动态接过程。 ◆解释了Java接模式,以及它是如何应用在网络小应用程序和可扩展Java代码中的。 ◆帮助你编写更优雅、更高效的代码,以及构建能够被更加高效地编译、加裁和运行的应用程序。 ◆包含了一个用Perl构建接器的练习项目,项目文件可以从网络下载得到。 媒体推荐 “我很享受阅读这本对实现接器和加载器的众多技术和挑战进行有效概述的书。虽然书中的多数例子都集中在今天被广泛使用的三种计算机体系结构上,但这本书也包含了很多描述过去的一些有趣和古怪的计算机体系结构的注解。通过这些真实的战例,我断定作者本人真正经历了这些事情并存活了下来给我们讲述这个故事。” ——Guy Steele 作者简介 作者:(美国)莱文(John R.Levine) 译者:李勇 莱文(John R.Levine),是很多书籍的作者或合作者,包括Lex & Yacc(O'Reilly),Programming for Graphics Files in C and C++(Wiley),以及7-heIntemetforDummies(IDG)。他还是Journal of C Language Translation的荣誉退休发行人、comp.compilers新闻组的长期仲裁人员,以及某个最早的商用Fortran 77编译器的创建考。他在耶鲁大学获得了计算机科学的博士学位。 目录 第1章 接和加载 1.1 接器和加载器做什么? 1.2 地址绑定:从历史的角度 1.3 接与加载 1.4 编译器驱动 1.5 接:一个真实的例子 练习 第2章 体系结构的问题 2.1 应用程序二进制接口 2.2 内存地址 2.3 地址构成 2.4 指令格式 2.5 过程调用和寻址能力 2.6 数据和指令引用 2.7 分页和虚拟内存 2.8 Intel 386分段 2.9 嵌入式体系结构 练习 第3章 目标文件 3.1 目标文件中都有什么? 3.2 空目标文件格式:MS-DOS的COM文件 3.3 代码区段:UNIX的a.out文件 3.4 重定位:MS-DOS的EXE文件 3.5 符号和重定位 3.6 可重定位的a.out格式 3.7 UNIX的ELF格式 3.8 IBM 360目标格式 3.9 微软可移植、可执行体格式 3.10 Intel/Microsoft的OMF文件格式 3.11 不同目标格式的比较 练习 项目 第4章 存储空间分配 4.1 段和地址 4.2 简单的存储布局 4.3 多种段类型 4.4 段与页面的对齐 4.5 公共块和其他特殊段 4.6 接器控制脚本 4.7 实际中的存储分配 练习 项目 第5章 符号管理 5.1 绑定和名字解析 5.2 符号表格式 5.3 名称修改 5.4 弱外部符号和其他类型符号 5.5 维护调试信息 练习 项目 第6章 库 6.1 库的目的 6.2 库的格式 6.3 建立库文件 6.4 搜索库文件 6.5 性能问题 6.6 弱外部符号 练习 项目 第7章 重定位 7.1 硬件和软件重定位 7.2 接时重定位和加载时重定位 7.3 符号和段重定位 7.4 基本的重定位技术 7.5 可重接和重定位的输出格式 7.6 其他重定位格式 7.7 特殊情况的重定位 练习 项目 第8章 加载和覆盖 8.1 基本加载 8.2 带重定位的基本加载 8.3 位置无关代码 8.4 自举加载 8.5 状结构的覆盖 练习 项目 第9章 共享库 9.1 绑定时间 9.2 实际的共享库 9.3 地址空间管理 9.4 共享库的结构 9.5 创建共享库 9.6 使用共享库接 9.7 使用共享库运行 9.8 malloc hack和其他共享库问题 练习 项目 第10章 动态接和加载 10.1 ELF动态接 10.2 ELF文件内容 10.3 加载一个动态接程序 10.4 使用PLT的惰性过程接 10.5 动态接的其他特性 10.6 运行时的动态接 10.7 微软动态接库 10.8 OSF/1伪静态共享库 10.9 让共享库快一些 10.10 几种动态接方法的比较 练习 项目 第11章 高级技术 11.1 C++的技术 11.2 增量接和重新接 11.3 接时的垃圾收集 11.4 接时优化 11.5 接时代码生成 11.6 Java接模型 练习 项目 参考文献 序言 几乎从有计算机以来,接器和加栽器就是软件开发工具包中的一部分,因为它们允许使用模块(而不是一个单独的大文件)来构建程序的关键工具。 早在1947年,程序员们就开始使用原始的加载器:将程序的例程存储在多个不同的磁带上,并将它们合并、重定位为一个程序。在20世纪60年代早期,这些加栽器就已经发展得相当完善了。由于那时内存很贵且容量有限,计算机的速度很慢(以今天的标准),为了创建复杂的内存覆盖策略(以将大容量的程序加载到小容量内存中),以及重新编辑先前接过的文件(以节省重新创建程序的时间),这些接器都包含了很多复杂的特性。 20世纪七八十年代,接技术几乎没有什么进展。接器趋向于更加简单,虚拟内存技术将应用程序和覆盖机制中的大多数存储管理工作都转移给了操作系统,越来越快的计算机和越来越大的磁盘也使得重新接一个程序或替换个别模块比仅仅接改变过的地方更加容易了。从20世纪90年代起,接器又开始变得复杂起来,增加了诸多现代特性,包括对动态接共享库的支持和对C++独特要求的支持。同时,像IA64那样具有宽指令字和编译时访存调度特性的先进处理器架构,也需要将一些新的特性加入到接器中,以确保在被接的程序中可以满足代码的这些复杂需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迂者-贺利坚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值