首页 > 其他分享 >王道408---DS---树、二叉树、图

王道408---DS---树、二叉树、图

时间:2023-10-12 17:35:02浏览次数:35  
标签:结点 return int --- 二叉树 Root1 DS Root2

有序树、无序树的概念

有序树和无序树,树中结点的各子树从左到右是有次序的,不能互换,称该树为有序树,否则称为无序树。

树/二叉树的性质

树的性质

image-20231006153618412

常用的只有第一个

二叉树的性质

image-20231006153719700

常用公式也只有这一个

二叉树的存储

一般分为顺序存储与链式存储

要求顺序存储能默写

顺序存储:

typedef struct TreeNode {
    int data;       //结点中的数据元素
    bool isEmpty;   //结点是否为空
} TreeNode;

//初始化顺序存储的二叉树,所有结点标记为"空"
void InitSqBiTree (TreeNode t[], int length) {
    for (int i=0; i<length; i++){
        t[i].isEmpty=true;
    }
}

int main(){
    TreeNode t[100];        //定义一棵顺序存储的二叉树
    InitSqBiTree(t, 100);   //初始化为空树
    //...
}
//判断下标为 index 的结点是否为空
bool isEmpty(TreeNode t[], int length, int index){
    if (index >= length || index < 1) return true;   //下标超出合法范围
    return t[index].isEmpty;
}

//找到下标为 index 的结点的左孩子,并返回左孩子的下标,如果没有左孩子,则返回 -1
int getLchild(TreeNode t[], int length, int index){
    int lChild = index * 2;   //如果左孩子存在,则左孩子的下标一定是 index * 2
    if (isEmpty(t, length, lChild)) return -1;  //左孩子为空
    return lChild;
}

//找到下标为 index 的结点的右孩子,并返回右孩子的下标,如果没有右孩子,则返回 -1
int getRchild(TreeNode t[], int length, int index){
    int rChild = index * 2 + 1;                 //如果右孩子存在,则右孩子的下标一定是 index * 2 + 1
    if (isEmpty(t, length, rChild)) return -1;  //右孩子为空
    return rChild;
}

//找到下标为 index 的结点的父节点,并返回父节点的下标,如果没有父节点,则返回 -1
int getFather(TreeNode t[], int length, int index){
    if (index == 1) return -1;          //根节点没有父节点
    int father = index / 2;             //如果父节点存在,则父节点的下标一定是 index/2,整数除法会自动向下取整
    if (isEmpty(t, length, father)) return -1;
    return father;
}


线索二叉树

1、先序遍历的线索二叉树不能直接找到度为2的前驱
2、后序遍历的线索二叉树不能直接找到度为2的后继

树和图的存储

二叉树的存储一般采用链表或数组

一般的树的存储手段有三种

1、双亲表示法
img
2、孩子表示法
img

有点像邻接表

3、孩子兄弟表示法
img

哈夫曼树的一些性质

带权路径长度的概念

在许多应用中,树中结点常常被赋予一个表示某种意义的数值,称为该结点的权。从树的根到任意结点的路径长度(经过的边数)与该结点上权值的乘积,称为该结点的带权路径长度。树中所有叶结点的带权路径长度之和称为该树的带权路径长度,记为

\[\mathrm{WPL}=\sum_{i=1}^{n}w_{i}l_{i} \]

其中带权路径长度(WPL)最小的二叉树称为哈夫曼树

哈夫曼树不一定是是一棵完全二叉树

树中一定没有度为1的结点

树中两个权值最小的结点一定是兄弟结点

树中任一非叶结点的权值一定不小于下一层任一结点的权值

计算机网络中A,B,C类网络的划分以及动态子网的划分,其思想与哈夫曼编码如出一辙

并查集

自从大纲改版还没考过,感觉今年很可能考,这是个重点!最次也要会默写朴素算法的并查集

代码如下(涉及了路径压缩、小树合并到大树等优化策略)

#include <stdio.h>
#define MAXSIZE 50
int UFSets[MAXSIZE];

void InitUFSets(int S[]){
    for(int i=0;i<MAXSIZE;i++){
        S[i] = -1;
    }
}

int find(int S[],int x){
    if(S[x] == -1) return x;           // -1说明到底了
    return find(S,S[x]);
}

int pathCompFind(int S[],int x){         // 路径压缩策略优化Find 操作
    if(S[x] >= 0){
        S[x] = find(S,S[x]); 
        return S[x];
    }
    return x;
}


bool UnionElem(int S[],int elem1,int elem2){    //王道书上是直接合并的root,而不是元素成员
    int first = find(S,elem1);
    int second = find(S,elem2);
    if(first != second){
        printf("%d -- %d\n",first,second);
        S[second] = first;
        return 1;
    }
    return 0;
}

bool UnionRoot(int S[],int Root1,int Root2){
    if(Root1 == Root2) return 0;    //比较两个根是否来自同一集合
    S[Root2] = Root1;               // 将根Root2连接到Root1上
    return 1;
}

bool optUnionRoot(int S[],int Root1,int Root2){
    if(Root1 == Root2) return 0;
    if(S[Root2] > S[Root1]){   // Root2 结点数更少         // 因为初始化的时候S的值全为 -1  所以 若S[Root1]与S[Root2]相加后为更小的负数
                                                            //较小的树,树较大,这也是为什么 S[Root1] >= S[Root2]时 却把Root2合并到Root1中的原因
        S[Root1] += S[Root2];       // 累加节点个数
        S[Root2] = Root1;
    }else{
        S[Root2] += S[Root1];
        S[Root1] = Root2;
    }
    return 1;
}

void debug(){
    for(int i=0;i<MAXSIZE;i++){
        printf("%d ",UFSets[i]);
    }
    puts("");
}

int main(){
    InitUFSets(UFSets);
    int arr[100] = {0,1,2,3,4,5,6,7,8,9};
    for(int i=0;i<=10;i++){
        UnionElem(UFSets,arr[i*2],arr[i*2+1]);
        // 0 -- 1
        // 2 -- 3
        // 4 -- 5
        // 6 -- 7
        // 8 -- 9
    }
    UnionElem(UFSets,1,3);
    UnionElem(UFSets,5,7);
    // 0 -- 1
    // 2 -- 3
    // 4 -- 5
    // 6 -- 7
    // 8 -- 9
    // 0 -- 2
    // 4 -- 6

    UnionElem(UFSets,1,6);
    UnionElem(UFSets,2,7);
    // debug();

    return 0;
}

朴素算法代码如下

#define SIZE 13
int UFSets[SIZE];		//用一个数组表示并查集

//初始化并查集
void Initial(int S[]){
    for(int i=0;i<SIZE;i++)			
        S[i]=-1;
}

//Find “查”操作,找x所属集合(返回x所属根结点)
int Find(int S[],int x){
    while(S[x]>=0)			//循环寻找x的根
        x=S[x];
    return x;						//根的S[]小于0
}

//Union “并”操作,将两个集合合并为一个
void Union(int S[],int Root1,int Root2){
  	//要求Root1与Root2是不同的集合
  	if(Root1==Root2)	return;		
  	//将根Root2连接到另一根Root1下面
    S[Root2]=Root1;
}

树、森林、二叉树遍历对应关系

image-20231006164649384

这里需要注意的是

  1. 树的后根遍历实际上就是树的中序遍历,只不过写法的问题
  2. 森林的中序遍历实际上是对森林后序遍历,其结果等价于对应二叉树的中序遍历,不知道为什么给起了一个中序遍历的名字,可能是其无法进行真正的中序遍历的原因吧

如图:

image-20231006165120982

对森林中序遍历(实质上是后序遍历)可得到 BCDAFEHIG ,等价于对二叉树的中序遍历

标签:结点,return,int,---,二叉树,Root1,DS,Root2
From: https://www.cnblogs.com/lordtianqiyi/p/17760058.html

相关文章

  • IMX6ULL裸机-RTC定时器
    1引入RTC定时器RTC定时器被叫做实时时钟(realtimeclock)。CPU内部有很多定时器,像看门狗WDT,PWM定时器,高精度定时器Timer等等,只在“启动”即“通电时”运行,断电时停止。当然,如果时钟不能连续跟踪时间,则必须手动设置。那么当关机后就没办法自动计数统计时间了。定时器的本质就......
  • Fi-GNN: Modeling Feature Interactions via Graph Neural Networks for CTR Predicti
    目录概Fi-GNN代码LiZ.,CuiZ.,WuS.,ZhangX.andWangL.Fi-GNN:Modelingfeatureinteractionsviagraphneuralnetworksforctrprediction.CIKM,2019.概"图网络"用在精排阶段(算哪门子图网络啊).Fi-GNN一个item可能有多种field,比如:\[\underbrace......
  • python+playwright 学习-61 Playwright 和 Selenium 的区别是什么?
    前言最近有不少同学问到Playwright和Selenium的区别是什么?有同学可能之前学过selenium了,再学一个playwright感觉有些多余,可能之前有项目已经是selenium写的了,换成playwright需要时间成本,并且可能有未知风险。也有同学之前可能没学过selenium,现在正准备入手一个web......
  • 2020-2021 ICPC, NERC, Southern and Volga Russian Regional Contest (Online Mirror
    有五种种类的垃圾,数量分别为\(a_1,a_2,a_3,a_4,a_5\)。第一种为纸质垃圾第二种为塑料垃圾第三种双非垃圾第四种基本纸质垃圾第五种基本塑料垃圾有三种垃圾桶,容量分别为\(c_1,c_2,c_3\)。第一种垃圾桶可以放入:纸质垃圾和基本纸质垃圾第二种垃圾桶可以放入:塑料......
  • Python - 深拷贝一个带有指向自身引用的列表,会报错么?紧接着用==比较,会报错么?
    问题描述深拷贝一个带有指向自身引用的列表:列表x中有指向自身的引用,因此x是一个无限嵌套的列表。importcopyx=[1]x.append(x)>>x[1,[...]]y=copy.deepcopy(x)>>y[1,[...]] 深拷贝不报错但是我们发现深度拷贝x到y后,程序并没有出现stackoverf......
  • Java设计模式-单例模式
    1、用到过的场景需要一样的对象放入数组中构建类的方式固定2、饿汉模式(不要用)packagecom.cc.eed.sin;/***<p>单例模式-饿汉(线程不安全)</p>**@authorCC*@since2023/10/12*/publicclassSingletonDemo2{privatestaticfinalSingletonDemo2......
  • import, export,export default,exports - 导入导出方法总结
    1.Export注意:在一个模块中,export可以向外暴露多个注意;使用export导出的成员,必须严格按照导出时候的名称,不能自定义,来使用{}按需接收注意;使用export导出的成员,如果要换个名称,可以使用as起别名模块是独立的文件,该文件内部的所有的变量外部都无法获取。如果希望获取某个变......
  • Backtrader - AttributeError: 'OptReturn' object has no attribute 'datas'
    1.0ErrorTraceback(mostrecentcalllast):File"D:/PycharmProjects/dbpower.backtrader.001/app/main_machine_learning.py",line191,in<module>img=cerebro.plot(style='line',plotdist=0.1,grid=True)File"D:\P......
  • 快速运维 - 防火墙
    防火墙firewalld存放配置文件有两个目录/usr/lib/firewalld和/etc/firewalld前者存放了一些默认的文件,后者主要是存放用户自定义的数据,所以我们添加的service或者rule都在后者下面进行。server文件夹存储服务数据,就是一组定义好的规则。zones存储区域规则firewalld.co......
  • 体验提升-一个“小技巧”彻底解决锦礼商品可见不可售
    一、背景锦礼平台,作为一家企业级B2B2C电商平台,同时服务于企业客户和企业员工,因此需要遵循企业客户的政策规范,确保商城内商品符合规定,并提升员工购物体验。然而,这种独特的运营模式导致锦礼平台上商品的可见不可售问题较为突出,对最终消费者的购物体验和平台的产品和业务产生了较大......