计算机程序设计艺术一二叉树

article/2025/10/20 22:39:48

计算机程序设计艺术一二叉树

概念:

        一个有限的节点集合,它或者为空,或者由一个根连同两个二叉树组成。

二叉树的自然方法:

        在每个节点内,有两个链接,LLINK和RLINK以及作为“指向树的指针”的链接变量T(T是NULL或者指向根节点)。如果这棵树为空,T = NULL;否则T是树的根节点的地址,而LLINK(T)和RLINK(T)分别是指向根的左子树和右子树的指针。

自然方法的实现示意图:


对树的操作:

        遍历或者“走遍”一棵树的概念。(系统地考虑树的节点,使得3每个节点恰被访问一次的方法。)
        常用的遍历二叉树的方法:先根序、中根须、后根序(皆为递归)。

遍历过程:

1.当二叉树为空时,什么都不做;否则进入2

2.
先根序中根序后根序
访问根遍历左子树遍历左子树
遍历左子树访问根遍历右子树
遍历右子树遍历右子树访问根

遍历算法:

1.中根序遍历二叉树

        使用了辅助栈A。
        T1.【初始化】置栈A为空,并置链接变量P = T;
        T2.【P = NULL ?】如果p = NULL,转到步骤T4;
        T3.【将P中值放入栈A】(现在P指向要加以遍历的一个非空二叉树)将P放入A;然后置P = LLINK(P)并返回到        T2。
        T4.【将A中缓存的值放入P】如果栈A为空,则算法终止:否则置P = A
        T5.【访问P】访问NODE(P),然后置P = RLINK(P),并返回到步骤T2。
        
        以下为流程图:


代码实现算法:

//代码实现二叉树中序根遍历
/*
*节点
*/
typedef struct node
{int values;struct node *llink;struct node *rlink;
}node, *node_p;node_p T; //指针
node_p A;//上一个节点void inorder_traversal()
{node_p p;A = NULL;p = T;while(true){while(p != NULL){A = p;p = p->llink;}if(A = NULL){return;}else{p = A;}printf("   %d   \n", p->values);//NODE(p)p = p->rlink;}
}
//end

2.先根序遍历二叉树:

        书上说是,用几乎一样的算法可以设计先根序遍历的算法。

        我猜一下:

        利用一个辅助栈A,存储上一个节点的地址,访问NODE(p)的意思就是访问当前p指向的节点。它的位置决定了算法是先序还是中序.
        R1.【初始化】置栈A为空,并置链接变量p = T;
        R2.【p = NULL?】如果A为空,转到步骤R4;
        R3.【访问p】置A =p,访问NODE(p),然后置p = LLINK(p);并放回步骤R2;
        R4.【将栈中的值置入p】如果栈A为空,则算法终止;否则置将栈中的值置入p;
        R5.【转向右子树】 p = RLINK(p).转到R2.

代码实现

//代码实现
void preorder_travering()
{node_p p;A = NULL;p = T;while(true){while(p != NULL){A = p;printf("   %d   \n", p->values);//NODE(p)p = p->llink;}if(A = NULL){return;}else{p = A;}p = p->rlink;}

}

为了描述方便引入的标号

        p* = 先根序下NODE(p)的后继的 地址;
        p$ = 在中根序下的NODE(p)的后继的地址;
        p# = 在后根序下NODE(p)的后继的地址;
        *p = 在先根序下的NODE(p)的前驱的地址;
        $p = 在中根序下的NODE(p)的前驱的地址
        #p = 在后根序下的NODE(p)的前驱的地址.
        令INFO(p)是树中的NODE(p)的值部分。

        如果NODE(p)没有这样的后继或前驱,一般使用LOC(T)的 值,其中T是指向根节点的指针 。

引入标号之后产生的公式:

*(p*) = (*p)* = p,$(sp$) = ($p)$ = p,#(p#) = (#p)# = p。

标号和二叉树举例:


其中,穿线二叉树是,带有链接前驱后继的虚线的二叉树。
算法S:(在穿线二叉树中的对称序(中根序)后继)
如果P指向穿线二叉树的一个节点,这个算法置Q = P$。
S1.【RLINK(p)是一个穿线吗?】置Q = RLINK(p)。如果RTAG(p) = 2终止算法.
S2.【向左搜索】如果LTAG(Q) = 0,置Q = LLINK(Q),并重复这一步骤。否则终止算法。

穿线二叉树计算机表示举例:


        程序表示穿线二叉树时,节点设计为双字:

LTAGLLINKINFO1
RTAGRLINKINFO2

        在无穿线树中,LTAG和RTAG将总是“+”表示,而终端链接将通过零表示。在穿线树中,将使用“+”来代表0,用“-”代表1。

算法:(插入到穿线二叉树中)如果树为空(即如果RTAG(p) = 1),这个算法就把节点NODE(Q)作为NODE(p)的右子树附加上来;否则就把NODE(Q)插到NODE(p)和NODE(RLINK(p))之间,使得后一节成为NODE(Q)的右子节点。假定发生插入的二叉树是上边图中那样。
        I1.【调整标志和链接】RLINK(Q) = RLINK(p),RTAG(Q) = RTAG(p),RLINK(p) = Q,RTAG(p) = 0, LLINK(Q) = p, LTAG(Q) = 1;
        I2.【RLINK(p)是穿线吗?】如果RTAG(Q) = 0,置LLINK(Q$) = Q。(这里Q$由算法S确定,即使LLINK(Q$)现在指向NODE(p)而不是NODE(Q),它仍将正确地工作。仅当插入到穿线的中间而不仅仅是插入新叶的这个步骤必要。)

森林和二叉树的自然对应:

通过某种变换过程,任何二叉树对应于着一个森林。

森林转二叉树的转换描述:

        令F = (T1, T2, T3, ... ,Tn)是树的森林。对应于F的二叉树B(F)可严格地定义如下:
        a)如果n = 0,则B(F)为空。
        b)如果n > 0,则B(F)的根是root(T1);B(F)的左子树是B(T11, T12,...,T1m),其中T11,T12,...,T1m是root(T1)的子树;且B(F)的右子树是B(T2,..., Tn)。

复制一个二叉树的算法:

设HEAD是一个二叉树T的表头地址。于是,T是通过LLINK(HEAD)抵达的HEAD的左子树。令NODE(U)是带有空左子树的一个节点。这个算法给出T的一个副本而且这个副本变成NODE(U)的左子树。如果NODE(U)是一个空的二叉树的表头,则这个算法把空树变成为T的一个副本。
C1.【初始化】置P = HEAD,Q = U。转到C4。
C2.【右边有任何东西?】如果NODE(P)有一个非空的右子树,置R = AVAIL,并把NODE(R)附加到NODE(Q)的右边。(在步骤C2开始时,NODE(Q)的右子树为空)
C3.【复制INFO】置INFO(Q) = INFO(P)。(注:INFO和以前的意思有点不一样,这里表示节点中除链接之外的所有部分)
C4.【左边有任何东西?】如果NODE(P)有一个非空的左子树,置R = AVAIL,并把NODE(R)附加到NODE(Q)的左边。(注:在步骤4开始前,NODE(Q)的左子树为空)
C5.【前推】置P = P*, Q = Q*。
C6.【检查完成否】如果P = HEAD(或等价地如果Q = RLINK(U),假定NODE(U)有一个非空的右子树),算法结束;否则转到步骤C2。



http://chatgpt.dhexx.cn/article/xdw5iF1T.shtml

相关文章

《计算机程序设计艺术》

计算机程序设计艺术(国防工业出版社) 《计算机程序设计艺术》重译自Donald E. Knuth(汉名 高德纳)的三卷著作:"The Art of Computer Programming: 1. Fundamental Algorithms; 2. Seminumerical Algorithms; 3. Sorting and Searching&q…

计算机程序设计艺术 介绍

《计算机程序设计艺术 》(The Art of Computer Programming ),簡稱TAOCP,是高德纳 (Donald Ervin Knuth)编著的关于计算机程序设计的七卷本著作。作者並因此获得美国计算机协会1974年 图灵奖 。[1] 目录 …

ici isi_ISI的完整形式是什么?

ici isi ISI:印度标准协会/服务间情报/印度统计研究所 (ISI: Indian Standards Institute / Inter-Service Intelligence / Indian Statistical Institute) 1)ISI:印度标准协会 (1) ISI: Indian Standards Institute) ISI is an abbreviation of the Ind…

lio linux工具,ISCSI (简体中文)/LIO (简体中文)

翻译状态:本文是 ISCSI_Target 的翻译。上次翻译日期:2015-06-11。如果英文版本有所更改,则您可以帮助同步翻译。 The translation of this article or section does not reflect the original text. Reason: Not updated since 2015 (Discus…

ITIL与CI/CD

第一节:ITIL TIL即IT基础架构库(Information Technology Infrastructure Library), ITIL,信息技术基础架构库)由英国政府部门CCTA(Central Computing and Telecommunications Agency)在20世纪80年代末制订,现由英国商务部OGC(Office of Gove…

ionic

#一、ionic的安装运行 1.安装nodejs 2.npm install -g cordova ionic npm i -g cordova ionic 3.创建项目 ionic start myApp tabs 4.ionic -v 是ionic 的cli版本 5.ionic serve 6.ionic g component actionsheet 必写component // 根模块 告诉ionic如何组装应用 // 引入 angul…

Calico

Calico基本概念 Calico是针对容器,虚拟机和基于主机的本机工作负载的开源网络和网络安全解决方案。Calico支持广泛的平台,包括Kubernetes,OpenShift,Docker EE,OpenStack和裸机服务。Calico将灵活的网络功能与无处不在…

ITIL是什么意思?ITIL是什么?

ITIL是什么? ITIL是Information Technology Infrastructure Library的缩写,即:信息技术基础架构库。 ITIL是由英国政府部门CCTA(Central Computing and Telecommunications Agency)在20世纪80年代末开发的一套IT服务管理标准库,它…

iLLD简介

iLLD, 全称 Infineon Low Level Driver, AURIX 家族的开源软件包, 支持多种编译器, 硬件抽象, 包含Demo, 让外设的配置/初始化/使用更简单. iLLD提供了函数, 驱动和结构体, 实现3个层次的抽象: Special FunctionRegister Level: 通过名字访问寄存器位Driver Level: 封装寄存器…

手机浏览器怎么查看html,手机浏览器网页收藏在哪里查看

qq浏览器的收藏夹在哪里?现在的浏览器都有自己的收藏夹,QQ浏览器作为非常受大家欢迎的一款浏览器,它的收藏夹又在哪里呢?其实QQ浏览器的收藏夹是默认的,那怎么找到呢?以及QQ浏览器的收藏夹如何导入导出呢&a…

Android安卓自带的 WebView 浏览器内核更新

Android 自带的 WebView 更新 一、Android 7 在安卓7系统里,一般内置的浏览器内核为很低版本,如52.0.2743.100。导致前端的新语法不支持,如ES6的语法最基本的 async,媲美老 IE 的环境。 前言 在设置 - 应用 - 显示系统应用里面…

android 点击事件失效,安卓手机微信自带浏览器点击事件失效解决

在移动端做了个导航,长这样 原来结构是用的span 导航 绑定用的是jquery的.click $(.menu_icon).click(function () { $("#nav-phone").stop().animate({right:"0"},500); }) $(.close).click(function () { $("#nav-phone").stop().a…

利用ADB命令强制卸载oppo自带浏览器

前言 oppo手机是自带oppo浏览器的,这个自带的浏览器带有oppo推荐的负面新闻很多,而且有时也自动推送一些消息给用户,页面不够简洁,打开浏览器负面内容比较多,然后我想卸载发现被系统做了限制,不能卸载&…

android自带浏览器调试,Android 手机浏览器调试使用Chrome进行调试实例详解

搜索热词 使用PC上的 Chrome 远程调试手机端的页面 工具准备 手机端:chrome for Android,; PC端:安装谷歌浏览器(最好是最新版的开发者版本) USB 连接线,也就是你充电器的那条线 开启调试模式 使用 USB 连接你的电脑,并开启调试模…

手机自带浏览器的强大

移动端 在大移动端中,大部分都是人手一台手机,大部分机型系统不是ios就是安卓,但是作为h5前端必须得获取是ios还是安卓都是正常,可是你难以相信这个世界坑你的总是有 获取手机浏览器哪个系统 你们确定下面的方式能够获取的对吗&am…

请用android手机自带浏览器,还在用手机自带浏览器吗?推荐两款无广告、功能齐全的浏览器...

最近一段时间更新的安卓版有些多,进而很多苹果的朋友就表示不开森。小编也是秉承免费分享黑科技的口号,大家应该都懂,苹果端的限制比较多,所以有时候安卓的有苹果的不一定有,大家一定要谅解呀。 好吧,今天A…

Android开发打开手机自带浏览器

Android开发打开手机自带浏览器 创建一个页面&#xff0c;点击按钮跳转到手机自带浏览器并打开指定网站。 1.首先编写页面布局 在activity_main.xml文件中编辑页面布局 <?xml version"1.0" encoding"utf-8"?> <RelativeLayoutxmlns:android&q…

调用Android自带浏览器打开网页

转载请注明出处: http://blog.csdn.net/lowprofile_coding/article/details/77928608 在Android中可以调用自带的浏览器&#xff0c;或者指定一个浏览器来打开一个链接。只需要传入一个uri&#xff0c;可以是链接地址。 启动android默认浏览器 在Android程序中我们可以通过…

探讨Android中的内置浏览器和Chrome

1.Android默认浏览器和Chrome的区别 Android出厂自带的浏览器&#xff1a;安卓WebKit浏览器&#xff0c;也成内置浏览器或者默认浏览器。 安卓WebKit不是Chrome。Chrome浏览器在它的用户代理字符串中有Chrome&#xff0c;但是安卓WebKit浏览器中没有。 最新的安卓WebKit的浏览器…