数据结构之树与二叉树——算法与数据结构入门笔记(五)_叉树的括号表示法如图所示 上面5棵二叉树中,从左至右,每棵二叉树的括号表示法依次(1)

最后

Python崛起并且风靡,因为优点多、应用领域广、被大牛们认可。学习 Python 门槛很低,但它的晋级路线很多,通过它你能进入机器学习、数据挖掘、大数据,CS等更加高级的领域。Python可以做网络应用,可以做科学计算,数据分析,可以做网络爬虫,可以做机器学习、自然语言处理、可以写游戏、可以做桌面应用…Python可以做的很多,你需要学好基础,再选择明确的方向。这里给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

👉Python所有方向的学习路线👈

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

👉Python必备开发工具👈

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

👉Python全套学习视频👈

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

👉实战案例👈

学python就与学数学一样,是不能只看书不做题的,直接看步骤和答案会让人误以为自己全都掌握了,但是碰到生题的时候还是会一筹莫展。

因此在学习python的过程中一定要记得多动手写代码,教程只需要看一两遍即可。

👉大厂面试真题👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

二叉搜索树是一种特殊的二叉树,又称为二叉查找树、二叉排序树等等,它实际上是数据域有序的二叉树,即对树上的每个结点,都满足其左子树上所有结点的数据域均小于根结点的数据域,右子树上所有结点的数据域均大于根结点的数据域。

在这里插入图片描述
二叉排序树意味着二叉树中的数据是排好序的,顺序为左结点<根节点<右结点,这表明二叉排序树的中序遍历结果是有序的(二叉树四种遍历方式[前序遍历、中序遍历、后序遍历、层序遍历]将在下面给出)。

二叉搜索树的特点:

  1. 每个节点包含一个值,每个节点至多有两个子树。
  2. 每个节点左子树节点的值都小于自身的值,每个节点右子树节点的值都大于自身的值。
  3. 二叉搜索树的查询时间复杂度是

O

(

log

N

)

O(\log N)

O(logN),但是随着不断的插入、删除节点,二叉树的树高可能会不断变大,当一个二叉搜索树所有节点都只有左子树或者都只有右子树时,其查找性能就退化成线性的了。

平衡二叉树

平衡二叉树又被称为 AVL 树,它在符合二叉搜索树的条件下,还满足“高度平衡”,即任何节点的两个子树的高度最大差为1。

在这里插入图片描述
平衡二叉树的产生是为了解决二叉搜索树在插入时发生线性排列的现象。平衡二叉树在插入或删除数据时,采用旋转的调整方式,使得二叉树在插入数据后保持平衡。平衡二叉树的查询时间复杂度最好情况和最坏情况都维持在

O

(

log

N

)

O(\log N)

O(logN)。但是频繁旋转会使插入和删除牺牲掉

O

(

log

N

)

O(\log N)

O(logN) 左右的时间,不过相对二叉搜索树来说,时间上稳定了很多。

红黑树

平衡二叉树(AVL)为了追求高度平衡,需要通过平衡处理使得左右子树的高度差必须小于等于1。高度平衡带来的好处是能够提供更高的搜索效率,其最坏的查找时间复杂度都是

O

(

log

N

)

O(\log N)

O(logN)。但是由于需要维持这份高度平衡,所付出的代价就是当对树种结点进行插入和删除时,需要经过多次旋转实现复衡。这导致 AVL 的插入和删除效率并不高。

为了解决这样的问题,红黑树被提出了。红黑树通过将结点进行红黑着色,使得原本高度平衡的树结构被稍微打乱,平衡程度降低。红黑树不追求完全平衡,只要求达到部分平衡。这是一种折中的方案,大大提高了结点删除和插入的效率,更加实用。

在这里插入图片描述
红黑树VS平衡二叉树

在这里插入图片描述
除了上面所提及的树结构,还有许多广泛应用在数据库、磁盘存储等场景下的树结构。比如B树B+树等。这里就先不介绍了诶。

树的应用

  1. 文件系统:文件系统通常使用树的结构来组织文件和目录。树形结构的特性使得文件系统可以方便地进行文件的查找、插入和删除操作。
  2. 数据库索引:数据库索引是一种数据结构,用于加快数据库中数据的访问速度。常见的数据库索引结构,如B树和B+树,利用树的特性实现高效的数据检索。
  3. 表达式解析:在编译器和解释器中,树结构常用于表示和解析数学表达式。表达式树(Expression Tree)可以将复杂的数学表达式转化为树的形式,便于计算和优化。
  4. 图形算法:许多图形算法,如最短路径算法和最小生成树算法,都可以使用树的结构进行表示和求解。树的特性可以帮助解决图形问题中的路径搜索和优化。

二叉树

二叉树的性质

  1. 在二叉树的第

i

i

i 层上至多有

2

i

1

2^{i-1}

2i−1 个结点

(

i

1

)

(i\ge1)

(i≥1)。
2. 深度为

k

k

k 的二叉树至多有

2

k

1

2^k-1

2k−1 个结点

(

k

1

)

(k\ge1)

(k≥1)。
3. 对任何一棵二叉树 T,如果度为0,其叶结点个数为

n

0

n_0

n0​,度为2的分支结点个数为

n

2

n_2

n2​,则有

n

0

n

2

1

n_0=n_2 + 1

n0​=n2​+1。
4. 具有

n

n

n 个结点的完全二叉树的深度为

log

2

n

1

\left\lfloor {{\log _2}n} \right\rfloor + 1

⌊log2​n⌋+1(

x

\left\lfloor x \right\rfloor

⌊x⌋表示不大于

x

x

x 的最大整数)。
5. 如果对一棵有

n

n

n 个结点的完全二叉树(其深度为

log

2

n

1

\left\lfloor {{\log _2}n} \right\rfloor + 1

⌊log2​n⌋+1)的结点按层序编号(从第1层到第

log

2

n

1

\left\lfloor {{\log _2}n} \right\rfloor + 1

⌊log2​n⌋+1 层,每层从左到右),则对于任意结点

i

i

i(

1

i

n

1\le i \le n

1≤i≤n) 有:
(1). 如果

i

=

1

i=1

i=1,则结点

i

i

i 是二叉树的根,无双亲;如果

i

1

i>1

i>1,则其双亲是结点

i

/

2

\left\lfloor i/2 \right\rfloor

⌊i/2⌋。
(2). 如果

2

i

n

2i>n

2i>n,则结点

i

i

i 无左孩子(结点

i

i

i 为叶子结点);否则其左孩子是结点

2

i

2i

2i。
(3). 如果

2

i

<

n

2i<n

2i<n,则结点

i

i

i无右孩子;否则其右孩子是结点

2

i

1

2i+1

2i+1。

二叉树的存储结构

二叉树的顺序存储结构
前面我们已经谈到了树的存储结构,并且谈到顺序存储对树这种—对多的关系结构实现起来是比较困难的。但是二叉树是—种特殊的树,由于它的特殊性,使得用顺序存储结构也可以实现。
顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树。因为不是完全二叉树会有空间的浪费。

二叉链表
既然顺序存储适用性不强,我们就要考虑链式存储结构。二叉树每个结点最多有两个孩子,所以为它设计一个数据域和两个指针域是比较自然的想法,我们称这样的链表叫做二叉链表。结点结构图如下表所示:

lchilddatarchild

其中 data 是数据域;lchild 和 rchild 都是指针域,分别存放指向左孩子和右孩子的指针。

以下是我们的二叉链表的结点结构定义代码:

/* 二叉树的二叉链表结点结构定义*/
typedef struct BiTNode			// 结点结构
{
	TElemType data;				 // 结点中的数据域
    struct BiTNode *lchild,*rchild;    // 左右孩子指针       
}BiTNode,*BiTree;

结构示意图如下图所示:

在这里插入图片描述

二叉树的遍历

二叉树的遍历(traversing binary tree)是二叉树的一种重要操作。二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树中的所有结点,使得每个结点被访问一次且仅被访问一次。

这里有两个关键词:访问和次序。访问其实是要根据实际的需要来确定具体做什么,比如对每个结点进行相关计算,输出打印等,它算作是—个抽象操作。在这里我们可以简单地假定访问就是输出结点的数据信息。

二叉树的遍历次序不同干线性结构,最多也就是从头至尾、循环、双向等简单的遍历方式。树的结点之间不存在唯一的前驱和后继关系,在访问一个结点后,下一个被访问的结点面临着不同的选择。

先序遍历

在这里插入图片描述
算法讲解

  • 若二叉树为空,则空操作返回,否则遍历顺序:根结点->左子树->右子树。
  • 动态图解:和上面的动态图一样,先序遍历就像一个小人从根结点开始,围绕二叉树的外圈开始跑(遇到缝隙就钻进去),按照跑的顺序,依次输出序列。

代码演示

void PreOrderTraversal(BiTree BT)
{
    if( BT != NULL ) 
    {
        printf(“%d\n”, BT->Data);        //对节点的数据进行打印          
        PreOrderTraversal(BT->Left);     //访问左子树
        PreOrderTraversal(BT->Right);    //访问右子树
    }
}

中序遍历

在这里插入图片描述
算法讲解

  • 若二叉树为空,则空操作返回,否则遍历顺序:左子树->根结点->右子树。
  • 动态图解:中序遍历就像投影仪一样,将二叉树从最左侧到最右侧依次投影到同一水平线上面,得到的从左到右的相关序列就是二叉树的中序遍历。

代码演示

void InOrderTraversal(BiTree BT)
{
    if(BT != NULL)
    {
        InOrderTraversal(BT->Left);
        printf("%d\n", BT->Data);
        InOrderTraversal(BT->Right);
    }
}

后序遍历

在这里插入图片描述
算法讲解

  • 若二叉树为空,则空操作返回,否则遍历顺序:左子树->右子树->根结点。
  • 动态图解:后序遍历就像剪葡萄,只能一个个剪,不能让超过1个的葡萄一起掉下来,那就错了。例如上图中的 B,剪去 B 后面的 D、E、H、I、J 都会掉下来(达咩),而 H 剪去只会掉下 H,规律就是这个规律。

代码演示

void PostOrderTraversal(BiTree BT)
{
    if (BT != NULL)
    {
        PostOrderTraversal(BT->Left);
        PostOrderTraversal(BT->Right);
        printf("%d\n", BT->Data);
    }
}

层次遍历

层次遍历就是从根节点开始,一层一层,从上到下,每层从左到右,依次取值。

代码演示

void LevelOrder(BiTree T){
	InitQueue(Q);				//初始化辅助队列
	BiTree p;
	EnQueue(Q,T);				//将根结点入队
	while(!IsEmpty(Q))
	{							//队列不空则循环
		DeQueue(Q,p);			//队头结点出队
		visit(p);				//访问出队结点
		if(p->1child!=NULL)
			EnQueue(Q,p->lchild);//左子树不空,则左子树根结点入队
		if(p->rchild!=NULL)
			EnQueue(Q,p->rchild);//右子树不空,则右子树根结点入队
	}
}

C语言

以下是使用C语言实现二叉树(包括创建树、插入结点、删除结点、遍历树、计算树的深度/高度和大小等基础操作)的示例代码:

#include <stdio.h>
#include <stdlib.h>

// 定义二叉树节点
typedef struct Node {
    int data;
    struct Node* left;
    struct Node* right;
} Node;

// 创建新节点
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    if (newNode == NULL) {
        printf("Memory allocation failed\n");
        return NULL;
    }
    newNode->data = data;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

// 插入节点(递归实现)
Node* insertNode(Node* root, int data) {
    if (root == NULL) {
        return createNode(data);
    } else {
        if (data <= root->data) {
            root->left = insertNode(root->left, data);
        } else {
            root->right = insertNode(root->right, data);
        }
        return root;
    }
}

// 删除节点
Node* deleteNode(Node* root, int data) {
    if (root == NULL) {
        return root;
    } else if (data < root->data) {
        root->left = deleteNode(root->left, data);
    } else if (data > root->data) {
        root->right = deleteNode(root->right, data);
    } else {
        if (root->left == NULL && root->right == NULL) {
            free(root);
            root = NULL;
        } else if (root->left == NULL) {
            Node* temp = root;
            root = root->right;
            free(temp);
        } else if (root->right == NULL) {
            Node* temp = root;
            root = root->left;
            free(temp);
        } else {
            Node* minRight = findMin(root->right);
            root->data = minRight->data;
            root->right = deleteNode(root->right, minRight->data);
        }
    }
    return root;
}

// 查找最小节点
Node* findMin(Node* root) {
    while (root->left != NULL) {
        root = root->left;
    }
    return root;
}

// 计算树的深度/高度
int calculateHeight(Node* root) {
    if (root == NULL) {


**一、Python所有方向的学习路线**

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。

![img](https://img-blog.csdnimg.cn/1d40facda2b84990b8e1743f5487d455.png)  
![img](https://img-blog.csdnimg.cn/0fc11d4a31bd431dbf124f67f1749046.png)

**二、Python必备开发工具**

工具都帮大家整理好了,安装就可直接上手!![img](https://img-blog.csdnimg.cn/ff266f529c6a46c4bc28e5f895dec647.gif#pic_center)

**三、最新Python学习笔记**

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

![img](https://img-blog.csdnimg.cn/6d414e9f494742db8bcc3fa312200539.png)

**四、Python视频合集**

观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

![img](https://img-blog.csdnimg.cn/a806d9b941c645858c61d161aec43789.png)

**五、实战案例**

纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。![img](https://img-blog.csdnimg.cn/a353983317b14d3c8856824a0d6186c1.png)

**六、面试宝典**

![在这里插入图片描述](https://img-blog.csdnimg.cn/97c454a3e5b4439b8600b50011cc8fe4.png)

![在这里插入图片描述](https://img-blog.csdnimg.cn/111f5462e7df433b981dc2430bb9ad39.png)

###### **简历模板**![在这里插入图片描述](https://img-blog.csdnimg.cn/646863996ac44da8af500c049bb72fbd.png#pic_center)




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值