《算法导论》学习总结——第三部分3二叉查找树

学习 《算法导论》第13章 红黑树 总结二 学习 《算法导论》第13章 红黑树 总结二在学习 《算法导论》第13章 红黑树 总结一中学习了红黑树的五个性质,红黑树的结构定义以及旋转。这节学习红黑树的插入和删除操作。红黑树的插入在一棵n个结点的红黑树中插入一个新结点的操作可以在O(lgn)时间内完成。红黑树的插入分为两步:第一步:把红黑树当成是一棵普通的二叉查找树,把新结点插入这棵二叉查找树;第二步:为保证红黑树的性质,将插入的新结点着色.第一 阅读详情

        查找树,也许是高级货,因为满足的性质蛮有型的,即left<root<right,其实算起来,和堆挺像的,只是堆是root > left(right),而且堆对左右就不怎么管了,如果效果好点,直接建个排序树,排序什么的,岂不直接就搞定了?

         说到这个,扯一下,上次看到一人说快速排序,虽说表面上核心算是划分,实际在背后有一颗二叉排序树。从这个观点来看,的确,每次划分,都是找到了子树的一个root节点,且大方向是left<right,其实这说法是很有道理的。而且从这个角度看,快排快于堆排序,也许是因为对左右孩子的大小限制了,而不像堆,只管root最大。

         不过二叉查找树的定义不是很严格,虽然比起堆来好了不少,只是限制left<root<right,这样的话,同样的数字组合,形成的排序树,高度会差很多,如下所示:

不过也许是因为这个原因,才有了更平衡的红黑树的引入啊,多和谐。

      习题12.1-3可参考: http://www.cnblogs.com/shuaiwhu/archive/2011/04/20/2065055.html用C++写的,哎,发现现在自己写的都特么C,哎。对于12.1-4,前序和后续遍历的递归,貌似就一种方式吧?以先序为例。额,这个莫非真能Θ(n)时间内搞定?

void PrintTree(BiTree T)
{ // 初始条件: 二叉树T存在;操作结果: 先序输出T的元素 
	if(T) // T不空 
	{
		cout << T->data<<" " ; // 输出根结点 
		PrintTree(T->lchild);  // 遍历左子树 
		PrintTree(T->rchild);  // 遍历右子树 
	}
}
        这边的一些对二叉树的基本操作,都蛮简单的,除了TREE-INSERT是个不错的过程外,伪代码如下:

TREE-INSERT(T, z)
1 y ← NIL
2 x ← root[T]
3 while x ≠ NIL
4   do y ← x
5     if key[z] < key[x]
6       then x ← left[x]
7     else x ← right[x]
8 p[z] ← y
9 if y = NIL
10    then root[T] ← z  //Tree T was empty
11    else if key[z] < key[y]
12      then left[y] ← z
13    else right[y]
       比如12.3-2和12.3-3提到,我们可以用反复插入的方式构造而查抄找树;也可以不断的插入构造二叉查找树,然后中序遍历输出,排序就好了,伪代码如下:

for i = 1 to n 
   TREE-INSERT(T,A[i])
INORDER-TREE-WALK(T.root)

        这样的排序,最坏情况下必然是O(n^2),在整个二叉树为一条线形的时候,其实这情况看起来跟偏瘫没什么两样。(虽然这种事情出现的概率很低,不过科学就是TMD的要注重严谨,所以啊,哎),TREE-INSERT为O(n)则整个就O(n2),最好情况为O(nlgn),当二叉树比较均衡,高度为lgn时。看到了吧, 跟快排的多么相似啊,最坏情况是二叉树线性时,最好就是二叉树均衡时,二叉树思想果然是快排提速的关键呢么?

         最后是本次实现的很粗糙的代码:(main函数上为测试序列:10 4 1 0 0 5 0 0 17 16 0 0 21 0 0)

#include <iostream>
using namespace std;

const int NIL=0;
//二叉查找树结构体
typedef struct BiTNode
{
	int data;
	struct BiTNode *lchild,*rchild ,*parent; //左右孩子,父指针
}BiTNode,*BiTree;
//基本操作
int InitBiTree(BiTree &T)
{ //构造空二叉树T
	T=NULL;
	return 1;
}
void DestroyBiTree(BiTree &T)
{ // 初始条件: 二叉树T存在。操作结果: 销毁二叉树T
	if(T) // 非空树 
	{
		if(T->lchild) // 有左孩子 
			DestroyBiTree(T->lchild); // 销毁左孩子子树 
		if(T->rchild) // 有右孩子 
			DestroyBiTree(T->rchild); // 销毁右孩子子树 
		delete T;
		//free(T); // 释放根结点 
		T=NULL; // 空指针赋0 
	}
}
void CreateBiTree(BiTree &T)
{ // 按先序次序输入二叉树中结点的值构造二叉链表表示的二叉树T。变量NIL表示空(子)树
	int key;
	cin >> key;
	if(key==NIL) // 空 
		T=NULL;
	else
	{
		T = new BiTNode;
		T->data=key; //* 生成根结点
// 		T->parent = NULL;
//  		if (T->rchild)
//  			T->rchild->parent = T;
//  		if (T->lchild)
//  			T->lchild->parent = T;
		CreateBiTree(T->lchild); //* 构造左子树 
		CreateBiTree(T->rchild); //* 构造右子树 
	}
}
int BiTreeEmpty(BiTree T)
{// 初始条件: 二叉树T存在 
	// 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE 
	if(T)
		return 0;
	else
		return 1;
}
int BiTreeDepth(BiTree T)
{ // 初始条件: 二叉树T存在。操作结果: 返回T的深度 
	int i,j;
	if(!T)
		return 0;
	if(T->lchild)
		i=BiTreeDepth(T->lchild);
	else
		i=0;
	if(T->rchild)
		j=BiTreeDepth(T->rchild);
	else
		j=0;
	return i>j ? i+1:j+1;
}
int Root(BiTree T)
{ // 初始条件: 二叉树T存在。操作结果: 返回T的根 
	if(BiTreeEmpty(T))
		return NIL;
	else
		return T->data;
}
int InsertChild(BiTree p,int LR,BiTree c) // 形参T无用 
{ // 初始条件: 二叉树T存在,p指向T中某个结点,LR为0或1,非空二叉树c与T 
	//           不相交且右子树为空 
	// 操作结果: 根据LR为0或1,插入c为T中p所指结点的左或右子树。p所指结点的 
	//           原有左或右子树则成为c的右子树 
	if(p) // p不空 
	{
		if(LR==0)
		{
			c->rchild=p->lchild;
			p->lchild=c;
		}
		else // LR==1 
		{
			c->rchild=p->rchild;
			p->rchild=c;
		}
		return 1;
	}
	return -1; // p空 
}
int DeleteChild(BiTree p,int LR) // 形参T无用 
{ // 初始条件: 二叉树T存在,p指向T中某个结点,LR为0或1 
	// 操作结果: 根据LR为0或1,删除T中p所指结点的左或右子树 
	if(p) // p不空 
	{
		if(LR==0) // 删除左子树 
			DestroyBiTree(p->lchild);
		else // 删除右子树 
			DestroyBiTree(p->rchild);
		return 1;
	}
	return -1; // p空 
}
void PrintTree(BiTree T)
{ // 初始条件: 二叉树T存在
	// 操作结果: 先序输出T的元素 
	if(T) // T不空 
	{
		cout << T->data<<" " ; // 访问根结点 
		PrintTree(T->lchild);  // 遍历左子树 
		PrintTree(T->rchild);  // 遍历右子树 
	}
}
int  TreeSearch(BiTree x , int k)
{//在查找树x中查找关键字k
	if (x)
	{
		if ( (x->data == NIL) || (k == x->data) )
			return x->data ;
		if ( k < x->data )
			return  TreeSearch( x->lchild , k ) ;
		else
			return  TreeSearch( x->rchild , k ) ;
	} 
	else
		return NIL;
}
int TreeMininum(BiTree x)
{//返回树T中的最小元素
	while (x->lchild != NIL)
		x = x->lchild;
	return x->data;
}
int TreeMaximum(BiTree x)
{//返回树T中的最大元素
	while (x->rchild != NIL)
		x = x->rchild ;
	return x->data;
}
//10 4 1 0 0 5 0 0 17 16 0 0 21 0 0
int main(int argc,char **argv)
{
	BiTree T;
	CreateBiTree(T);
	PrintTree(T);
	cout << endl;
	cout << "Max = " << TreeMaximum(T) << endl;
	cout << "Min = " << TreeMininum(T) << endl;
	cout << TreeSearch(T,11) << endl;
	DestroyBiTree(T);
	PrintTree(T);
	return 0;
}

     就没有实现TREE-INSERT和TREE-DELETE过程,TankyWoo的实现不错,还蛮详细,参考:http://www.wutianqi.com/?p=2430。本章搞定,下面红黑树了,哎呀,高级货~~


     菜鸟goes on ~~~


算法导论_15.5 最优二叉查找树 一、问题 将英文翻译成法语,使用平衡二叉树建立英语-法语单词的键值对,便于搜索; 文章中单词出现次数有频率,有些单词出现频繁, 有些单词出现概率很小;应当将频繁出现的单词放在距离根较近的地方; 此外,注意到有部分英语单词没有对应的法语翻译 访问一个结点的代价是:结点的深度+1; 我们已知英语文章中各类单词出现的频率,试图构造一棵最优二叉查找树,使得翻译文章的速度最快(访问的结点数最小); 翻译整篇英语文章,搜索单词的代价是: 我们已知pi, qi; 对于不同的depth(ki) 和depth(di), 求 阅读详情

相关推荐

算法导论学习笔记(七):二叉树

前言 昨天看算法导论看到二叉查找树,虽然以前学数据结构的时候已经学过了二叉树,但感觉自己很多东西已经忘了,为 了更好的学习二叉查找树以及后面所涉及到的二叉树方面的相关算法,故再一次复习了下二叉树。并在这写个复习笔 记,便于以后的复习。 定义 学习二叉树之前,肯定得了解数据结构中的树。数据结构中的树和我们现实中的树还是有一点区别的。首先数据结构 中的树与现实相比是倒立的。其次数据

3292

查找算法三之二叉排序树

在学习查找算法的时候说过,当时you对树的操作不熟练,所以关于二叉搜索树、B树这些动态查找都没有练习,这一节补上,这一节介绍二叉搜索树。    二叉搜索树,书上叫二叉排序树或者二叉查找树,首先看定义,二叉排序树或者是一颗空树,或者是具有下列性质的二叉树:(1)若他的左子树不空,则左子树上所有结点的值均小于它的根结点的值;(2)若他的右子树不空,则右子树上所有结点的值均大于它的根结点的值;(3)它

山之巅的专栏 1403

算法导论第13(十三)章红黑树

红黑树是一般的二叉查找树的一种较为”平衡的“

z84616995z的专栏 1万+

算法导论16.3-5--huffman树的表示

题目:假设有一个字母表C={0,1,2,3,4,...,n-1}上的最优前缀编码,我们想用尽可能少的位来传输。证明:C上的任意一个最优前缀编码都可由 2n-1+n*ceil(log(n)) 个位的序列来表示。(提示:用2n-1位说明树的结构,通过树的遍历来发现)解答:http://stackoverflow.com/questions/759707/efficient-way-of-storing...

weixin_30345577的博客 278

Leetcode题目分类指南(单独刷题或学习算法书籍配合使用)

Leetcode题目分类指南 笔者在学习《算法导论》同时,希望能够配合Leetcode的题目进行分类模块化练习,该分类为笔者自己根据做题学习经验,结合《算法导论》的内容,给出Leetcode题目分类。题目主要集中在Leetcode的前400题中,也包括有后面的一些经典值得刷的题。该题目分类按照算法和数据结构排版,即可供单独Leetcode刷题使用,也可以配合学习《算法导论》或者其他算法书籍...

locallucky的博客 8126

uniapp+ucharts折线图toolTip不显示?别慌,手把手教你用showToolTip方法精准修复

本文详细解析了uniapp+ucharts折线图中toolTip不显示的常见问题,提供了showToolTip方法的精准修复方案。从底层原理到实战代码,帮助开发者解决触摸事件冲突、坐标计算偏差等问题,确保折线图交互提示功能稳定运行。

weixin_30316097的博客 401

对于算法导论阅读的感想

对于算法导论的阅读排序对于算法导论的阅读 排序 选择排序和冒泡排序 堆排序 快速排序 计数排序 基数排序 木桶排序 选择排序和冒泡排序实际上就是暴力排序,一个是从多变少,一个是从少变多。 选择排序是对新数组成员进行选择而无需照顾源数组,而冒泡排序则是对源数组进行选择而无需照顾生成数组。 时间复杂度:O(n^2)堆排序乍一看,感觉和冒泡是神似的。因为他们都是通过对源数组进行选择而无需照顾生成数组

qq_27747035的博客 1746

PP生产订单的BADI增强 WORKORDER_UPDATE

我们的项目需求是: 1、 保存时检查工单BOM是否存在物料号相同的行项目,如果有则提示“物料& 重复,请检查工单BOM” 系统增强出口:PPCO0001,检查组件行项目是否有重复物料项 开始以为的增强增强看一下是用PPCO0001还是PPCO0007 后来找到了badi WORKORDER_UPDATE IF_EX_WORKORDER_UPDATE~BEFORE_UPDATE

ERP运维咨询(目标和成功) 4633

看《算法导论》的一点感想

转自byr论坛:http://bbs.byr.cn/#!article/Job/1152834,留下来以后学习用。 说实话,我没把那书看完,甚至没有看过1/10,至于做题就更没谱了,只要不是有人提起,我根本不知道哪个题居然在算导(下文简写成clrs)中出现过,但是我还要写一下我对这书的心得,看法和感受,尤其是和找工作的关系,供大家分享。 1.为什么看这本书?个人认为是为了学习解决计算机科学...

weixin_30376323的博客 684

新手如何学习车载底层嵌入式软件开发(AutoSar)

汽车嵌入式开发

ACarSoft的博客 4219

Java 大视界 -- Java+Spark MLlib 构建智能推荐系统:协同过滤算法实战与优化(441)

Java+Spark MLlib构建智能推荐系统实战 本文详细介绍了基于Java和Spark MLlib构建协同过滤推荐系统的全流程实践方案。主要内容包括: 架构设计:采用离线批处理为主、近实时更新为辅的架构,包含数据采集层、处理层、模型层、推荐生成层、存储层和应用层六大模块,可支撑千万级用户推荐需求。 技术实现: 使用Spark MLlib的ALS算法进行协同过滤模型训练 提供数据清洗、模型训练、推荐生成等核心代码实现 采用MySQL存储推荐结果,支持批量插入和事务保障 生产级优化: 版本化模型存储规避覆

【青云交】华为云云享专家 | 阿里云开发者社区专家博主 技术圈个人影响力前 9 | 博客之星 TOP12 优快云 首位四榜(原力榜 / 作者周榜 / 领军人物 / 综合热榜)榜首,破平台纪录! 苏州地区全榜霸榜,感恩全网十多万粉丝同行! 2519

查找算法(基于二叉排序树的查找)

1.二叉排序树的定义与描述 二叉排序树又称为二叉查找树,它是一种特殊的二叉树。 定义:二叉排序树是一颗空树或者是具有一下性质的二叉树。 1)若它的左子树非空,则左子树上所有的结点值均小于根结点的值。 2)若它的右子树非空,则右子树上所有的结点的值均大于(或等于)根结点的值。 3)它的左右子树也分别是二叉排序树。2.数据结构typedef struct node { KeyType

weimeng809的专栏 2万+

BLE蓝牙胎压监测

胎压监测系统新技术

qq_41851841的博客 1251

"《算法导论》之‘树’":二叉查找树

  树的介绍部分摘取自博文二叉查找树(一)、二叉查找树(二)、二叉查找树。 1. 树的介绍 1.1 树的定义   树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。      把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:  (1) 每个节点有零个或多个子节点;  (2) 没有父节点的节点称为根节点...

222

Vscode+ROS/ROS2 开发调试基于ROS/ROS2应用环境配置

在ROS操作系统开发应用程序时,我们常常需要调试代码,验证程序的正确性。但是在用rosrun或者roslaunch启动节点后,若程序运行过程中发生错误而导致发生出错停止工作,这时候终端并不会输出具体的信息指出在何处发生了错误,具体错误的原因又是什么。往往仅仅是core dump 或者segmentation fault 等等一类的模糊提示。

Chasinglight的博客 5800

openpi 入门教程(一)安装、训练、微调与推理

OpenPI是由物理智能团队发布的机器人开源模型和软件包,包含两种主要模型:基于流的扩散视觉-语言-动作模型(VLA)的π₀模型和基于FAST动作标记器的自回归VLA的π₀-FAST模型。这些模型已在超过10,000小时的机器人数据上进行了预训练,并提供了基础模型检查点,支持开箱即用或根据用户数据集进行微调。OpenPI的实验性质意味着它可能不适用于所有平台,但鼓励研究人员和从业者进行创造性实验。运行这些模型需要至少具备NVIDIA GPU,推荐使用RTX 4090或更高规格的显卡。OpenPI支持在Ubu

2506_90492529的博客 5104

《算法导论》读书笔记(总纲)

《算法导论》读书笔记(总纲))

北观止的博客 1321

YOLOv13改进策略【特征提取层】| CVPR-2024 PKI Module 获取多尺度纹理特征,适应尺度变化大的目标

PKI Module是。

Limiiiing的博客 275

【算法导论】第12章二叉查找树

1、问题引入   查找树是一种数据结构,它支持多种动态集合操作,包括构造、查找、插入、删除、寻找最小值、寻找最大值等,其中构造过程主要采用不断插入值来完成。   二叉查找树中的关键字存储方式满足以下性质:设x为二叉查找树中的一个节点,如果y是x的左子树中的一个节点,则y->data < x->data;如果y是x的右子树中的一个节点,则y->data > x-&g...

weixin_30872867的博客 93

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

算法导论中英文版下载

算法导论:  学过计算机的都知道,这本书可以说是全世界最权威的算法课程的大学课本了,基本上全世界的名牌大学用的教材都是它。这本书一共四位作者,Thomas H. Cormen,Charles E. Leiserson 和 Ronald L.Rivest 是来自 MIT 的教授,Clifford Stein 是MIT出来的博士,现在哥伦比亚大学做教授,四人姓氏的首字母联在一起即是此书的英文简称(

首席技术执行官CTO(Chief Technology Officer)|技术总监--邓斌博客 1万+

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

二叉排序树 java_二叉查找树的Java实现

转自:http://blog.youkuaiyun.com/lovesqcc/article/details/6246615为了克服对树结构编程的恐惧感,决心自己实现一遍二叉查找树,以便掌握关于树结构编程的一些技巧和方法。以下是基本思路:[1] 关于容器与封装。封装,是一种非常重要的系统设计思想;无论是面向过程的函数,还是面向对象的对象,都是实现抽象和封装的技术手段。要使系统更加安全更具可维护性,就应当将封装...

weixin_42467457的博客 291

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

算法导论——(3)红黑树

红黑树是在二叉查找树的概念基础上提出的,所以它具备二叉查找树的所有性质,比如一棵子树的根节点的键值比他左子树上面的元素的键值都大,比他右子树上元素的键值都小。在二叉查找树的性质基础上给每个节点加了一个属性:颜色,树的结点属性(color,left,right,p,key).并附加了五条约束: 1.树的根节点颜色为黑色。 2.节点的颜色只能是黑色或者红色。(当然自己可以随意定颜色区分) 3.每个

a591193965的博客 581

关于算法学习的总结和感悟(原创)

时隔一年重读《算法导论》,去年读到了二叉查找树就搁浅了,今年从头捡起,希望能走的 更远一些。算上大学时的数据结构与算法课,今年可以算是第三波学习攻势了。随着学习的深入, 对算法的学习渐渐有了些自己的看法和感悟。 一.为什么学习算法? 记得初学算法时不明白为什么费力分析程序的执行步骤后,还要用公式表达出来并求极值。 一遍遍的学习渐渐有了领悟:算法研究是用来做大事的!

西代零零发 1万+

算法导论-二叉查找树习题解

12.2-9 设T为一棵其关键字均不相同的二叉查找树,并设x为一个叶子节点,y是其父节点。证明:key[y]或者是T中大于key[x]的最小关键字,或者是T中小于key[x]的最大关键字。   若x是y的左节点,y是x的后继,此时key[y]是大于key[x]的最小关键字;若x是y的右节点,y是x的前驱,此时key[y]是小于key[x]的最大关键字。 12.4-2 请...

weixin_30432179的博客 363

算法导论实验三:二叉排序树、红黑树的基本操作实现

本次实验主要熟悉并实践了二叉查找树和红黑树的插入、删除、判断操作以及流程,红黑的相关操作要比二叉查找树复杂不少。

enheihei的博客 752
上一篇: vc6局域网聊天室,支持文件传输的完成和修改
下一篇: 面试题之丑数的C++实现求解(孤陋寡闻了,才知道丑数这么high的东东)
coder_xia
博客等级 码龄17年 151粉丝 143原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值