数据结构之二叉树,实现二叉树的创建与遍历,以及二叉树的一些练习题

news2024/11/23 7:24:40

目录

目录

一、二叉树的创建与遍历

1.创建二叉树

构建出来的树如图:

2.二叉树的销毁

3.二叉树的前序遍历[Leetcode144.力扣]

4.二叉树的中序遍历

5.二叉树的后序遍历

二、二叉树的实现

1.获取树中节点的个数

2.获取叶子节点的个数

3.获取第K层节点的个数

4.获取二叉树的高度[Leetcode104.]

5.判断是否为单值二叉树[leetcode965.]

6.检查两棵树是否相同[Leetcode100.]

7.判断是否为另一棵树的子树[Leetcode572.]

8.查找二叉树中值为x的节点

9.翻转二叉树[Leetcode226.]

10.对称二叉树[Leetcode101.]

11.二叉树的遍历[Nowcoder KY11.]

12.判断一棵二叉树是否为平衡二叉树[Leetcode110.]

13.二叉树的层序遍历

14.判断一棵树是否为完全二叉树

总结


一、二叉树的创建与遍历

1.创建二叉树

        从0创建一棵二叉树,首先需要定义树的节点结构,定义之后需要在内存中开辟空间,初始化节点,然后链接节点中的左右指针

typedef int TreeNodeDataType;

typedef struct TreeNode{
    TreeNodeDataType data;
    struct TreeNode * left;
    struct TreeNode * right;
}TDNode;

//在内存中开辟一个树的节点
TDNode * BuyTDNode(TreeNodeDataType x)
{
    TDNode * node = (TDNode *)malloc(sizeof(TDNode*));
    if(node == NULL)
        return;
    //创建好之后初始化
    node->data = x;
    node->left = NULL;
    node->right = NULL;
//创建一棵树
int main()
{
    TDNode* n1 = BuyTDNode(1);
	TDNode* n2 = BuyTDNode(2);
	TDNode* n3 = BuyTDNode(3);
	TDNode* n4 = BuyTDNode(4);
	TDNode* n5 = BuyTDNode(5);
	TDNode* n6 = BuyTDNode(6);


    n1->left = n2;
	n1->right = n4;
	n2->left = n3;
	n4->left = n5;
	n4->right = n6;
}

构建出来的树如图:

2.二叉树的销毁

        由于二叉树中的节点是动态开辟出来的内存空间,所以在不使用的时候需要动态销毁。

void DestoryTree(BTNode * root)
{
    free(root->left);
    free(root->right);
    root->val = 0;
    free(root);
}

//注意这里虽然free掉了root,但是这里只是形参,最后在主函数中应该把这个节点置空

 

3.二叉树的前序遍历[Leetcode144.力扣]

        给一棵树的根节点root,返回它节点值的前序遍历,前序遍历的顺序是:根节点-左孩子-右孩子,可以使用递归的方法,把每个子树都看成由左右孩子组成,访问根节点0,然后访问左节点1,此时把左节点1当作根节点0,若还有左节点1,继续访问,访问右节点2,返回到上一层的左节点1,再访问上一层的右节点,直到遍历完整棵树

//按照前序打印这棵树 
void PreOrder(struct TreeNode * root)
{
    if(root ==NULL)
        return;
    printf("%d ",root->data);
    PreOrder(root->left);
    PreOrder(root->right);
}

//打印结果: 1 2 3 4 5 6 

力扣 题解,首先这道题核心也是二叉树的前序遍历,但是要返回遍历的结果,Note中注释返回的结果需要自己开空间,即自己定义一个数组存放遍历的数,题中形参只给了根节点,和一个int * 类型(指针)的returnSize,这里的returnSize是返回的数组大小。

解题逻辑:首先判断树是否为空树,如果是空树return;如果不是空树则开始前序遍历,前序的顺序是根节点,左子树,右子树,所以可以使用递归的方法。首先动态开辟一个数组,  数组中存放遍历的结果,每遍历一个,数组的下标+1,即returnSize+1,如果遍历到空节点,返回上一层递归,再去递归它的左子树,右子树。

Traversal(struct TreeNode * root,int *returnNum,int *returnSize)
{
    //调用的人需要数组和数组的大小,1.可以返回结构体,2.返回指针
    //如果returnSize为int类型,当前的形参只是实参的临时拷贝,不改变实参
    //所以使用一个int * ,当解引用使用形参的时候,会改变实参。
    if(root ==NULL)
        return;
    returnNum[(*returnSize)++] = root->val;
    Traversal(root->left,returnNum,returnSize);
    Traversal(root->right,returnNum,returnSize);
}

int * preorderTraversal(struct TreeNode * root, int * returnSize)
{
    //先自己开辟要返回的数组  数组的类型为int 型,要返回int *类型,所以使用一个指针指向数组
    int * returnNum = (int *)malloc(sizeof(int *)*100);
    //returnSize 为返回的数组的大小 
    *returnSize = 0; // 初始化为0
    if(root ==NULL)
        return NULL;
    //前序遍历单独写一个函数
    Traversal(root,returnNum,returnSize);
    return returnNum;

看完别人的思路,感觉如下的方式写更优解,上面开辟的数组大小是固定的,可以写一个函数统计这棵树的节点个数,再去开辟。




int * preorderTraversal(struct TreeNode * root, int * returnSize)

4.二叉树的中序遍历

void Inorder(struct TreeNode * root)
{
    if(root == NULL)
        return;
    Inorder(root->left);
    printf("%d",root->data);
    Inorder(root->right);
}

5.二叉树的后序遍历

void PostOrder(struct TreeNode * root)
{
    if(root ==NULL)
        return;
    PostOrder(root->left);
    PostOrder(root->right);
    printf("%d",root->data);
}

二、二叉树的实现

1.获取树中节点的个数

使用分治思维,统计根节点的左右节点的个数。遇到左节点,再去统计它的左右节点个数,递归。

一种经典的错误写法如下

int TreeSize(struct TreeNode * root)
{
    if(root ==NULL)
        return;
    int size = 0;
        size++;
    TreeSize(root->left);
    TreeSize(root->right);
    return size;
}

这种写法错误的点在于,没有完全理解递归的栈帧。当定义size的时候,size是一个局部变量,返回的size并不是总共的size,统计出来的左右节点个数没有保存,也没有返回给上一层的根节点。

正确写法如下使用一个三目运算符,如果节点为空,返回0,如果不为空,统计左右节点的个数,再加上自己,即所求的所有的节点个数。

int TreeSize(struct TreeNode * root)
{
    return root ==NULL ? 0:TreeSize(root->left)+TreeSize(root->right) + 1;
}

2.获取叶子节点的个数

获取叶子节点个数,先明白叶子节点的定义就是没有左右子树的节点,那么在函数中可以写如果根为空,返回0,如果节点不为空,统计左右子树节点的叶子节点,叶子节点即为(root->left==NULL && root->right==NULL)代码如下:

int TreeSizeLeaf(struct TreeNode * root)
{
    if(root ==NULL)
        return 0;
    if(root->left && root->right ==NULL)
        return 1; 
    return TreeSizeLeaf(root->left)+TreeSizeLeaf(root->right);
}

3.获取第K层节点的个数

如图所示:因为这个结构为一棵二叉树,认为节点1为第一层,第一层只会有一个节点。如果现在要求1的第三层的节点个数[3,5,6],无法直接访问到,但是对于2和4[3,5,6]分别是他们的左子树和右子树,对于2和4,[3,5,6]是他们的第二层。对于[3,5,6]本身,他们就是第一层,如果第一层不为空,就返回1,如果第一层为空,返回0。

1的第三层 == 2的第二层(1的左子树)+4的第二层(1的右子树)

                 == (3的第一层(2的左子树)+空 (2的右子树))+(5的第一层(4的左子树)+6的第一层(4的右子树))

由此类推 求当前的第K层节点个数 == 左子树的K-1层+右子树的K-1层,直到k ==1,当k==1的时候,判断这个节点是否为空,如果为空,返回0,如果不为空返回1

int TreeLeveSize(struct TreeNode * root,int k)
{
    if(root ==NULL)
        return 0;
    if(k==1)
    {
        //这里不用再写判断是否为空,因为在调用递归的时候,已经先判断了
       return 1;
    }
    return TreeLevelSize(root->left,k-1)+TreeLevelSize(root->right,k-1);
}

4.获取二叉树的高度[Leetcode104.]

思路:比较当前节点的左右子树的深度,哪个高,返回哪个。树的深度如果只有根节点,深度为0,如果有左子树或者有右子树,深度为1。比较两个数的深度的时候需要有两个统计变量,哪个大返回哪个值+1,+1的原因在于,如果为空,则有0层,如果有一个节点,本层就是1,返回到上一层就是2。

int TreeHeight(struct TreeNode * root)
{
    if(root ==NULL)
        return 0;
    int lh = TreeHeight(root->left);
    int rh = TreeHeighr(root->right);
    return lh > rh? lh+1:rh+1;
}

5.判断是否为单值二叉树[leetcode965.]

题目:如果二叉树的每个节点都具有相同的值,那么这个树就是单值二叉树。题目链接:力扣

思路:当前节点为根节点,判断它和左右子树的值是否相同,如果相同,继续判断,先走到左子树,判断它和它的左右子树是否相同,相同再判断原来根节点的右子树,依次递归。

思想是顺着这个顺序,写代码可以反着写,即我遇到了我的左子树或者右子树和我的值不相同,就return false,如果相同,就继续判断,直到遍历完这棵树。在这里要注意,左右子树可能为空,如果为空就无法访问到val,所以要加上这个条件。

bool isUnivalTree(struct TreeNode * root)
{
    if(root==NULL)
        return true;
    if(root->left && root->left->val != root->val)
        return false;
    if(root->right && root->right->val !=root->val)
        return false;
    //如果有1个为false,就返回false
    return isUnivalTree(root->left) && isUnivalTree(root->right);
}

6.检查两棵树是否相同[Leetcode100.]

题目:给两棵二叉树的根节点p,q,编写一个函数来判断两棵树是否相同(如果两棵树在结构上相同,并且节点具有相同的值,则认为他们相同) 题目链接:力扣

思路:先判断它们的根是否相同,如果根相同,比较左子树,左子树相同,再比较右子树。如果都相同,再比较子节点的左子树和右子树。思路顺着写,代码反着写。

bool isSameTree(struct TreeNode * p,struct TreeNode * q)
{
    if(p==NULL && q==NULL)
        return true;
    if(p==NULL || q==NULL)
        return false;
    if(p->val != q->val)
        return false;
    return isSameTree(p->left,q->left) &&isSameTree(p->right,q->right)
}

7.判断是否为另一棵树的子树[Leetcode572.]

题目:给两棵二叉树root,subroot。检验root中是否包含和subroot具有相同结构和节点值的子树,如果存在,返回true,如果不存在,返回false。题目链接:力扣

思路:可以借用判断两个树是否相同的函数

//判断两棵树是否相同
bool isSameTree(struct TreeNode * p,struct TreeNode * q)
{
    if(p == NULL && q ==NULL)
        return true;
    if(p == NULL || q == NULL)
        return false;
    if(p->val != q->val)
        return false;
   return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}



bool isSubtree(struct TreeNode * root, struct TreeNode * subRoot)
{
    if(root ==NULL)
        return;
    if(isSameTree(root,subRoot))
        return true;
    //在左右子树中寻找 有一个为true就返回true;
    return isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot);
}

8.查找二叉树中值为x的节点

思路:先判断根,根的值 == x ,返回,如果不等于,再找到左子树,如果左子树的值相等返回,不相等去找右子树,找到返回,找不到返回null(找完了)

但是这里需要注意,如果在左子树中找到返回,返回之后给上一层,并没有返回给第一个函数的return,所以需要保存一个值,找到之后保存这个结果。

BTNode * Find(BTNode * root,int x)
 {
    if(root->data == x)
        return root;
   BTNode * ret1 =  Find(root->left,x)
      if(ret1)
         return ret1;
   BTNode * ret2 = Find(root->right,x)
      if(ret2)
         return ret2;
    return NULL;
}

9.翻转二叉树[Leetcode226.]

题目:给一棵二叉树的根节点root,翻转这棵树,并返回其根节点,题目链接:力扣

思路:给一个tmp交换,然后递归

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* invertTree(struct TreeNode* root){
    if(root ==NULL)
        return NULL;
    struct TreeNode * tmp = (struct TreeNode *)malloc(sizeof(struct TreeNode *));
    tmp = root->left;
    root->left = root->right;
    root->right = tmp;

    invertTree(root->left);
    invertTree(root->right);
    
    return root;

}

 

10.对称二叉树[Leetcode101.]

题目:给一个二叉树的根节点root,检查它是否轴对称。题目链接:力扣如图:

 思路:之前判断两个树是否相同,都是用左子树和左子树比较。这道题目可以使用递归的方法,比较左子树和右子树

bool _isSymmetric(struct TreeNode * p , struct TreeNode * q)
{
    if(p== NULL && q ==NULL)
        return true;
    if(p ==NULL || q==NULL)
        return false;
    if(p->val != q->val)
        retrun false;
    return _isSymmetric(p->left,q->right) && _isSymmetric(p->right,q->left);
}


bool isSymmetric(struct TreeNode * root)
{
    if(root == NULL)
        return false;
    return _isSymmetrict(root->left,root->right);
}

 

11.二叉树的遍历[Nowcoder KY11.]

题目:编写一个程序,读入用户输入的一串先序遍历的字符串,根据此字符串建立一个二值二叉树(以指针方式存储),例如:ABC##DE#G##F###,其中#表示的是空格,空格字符代表空树,建立起二叉树之后,再对二叉树进行中序遍历,输出遍历结果。

题目链接:二叉树遍历_牛客题霸_牛客网

题目思路:首先要重建这棵树,现在是以前序的遍历存储,根据前序再递归,分别存入到它的左右子树中。然后中序遍历输出

struct TreeNode 
{
    char val;
    struct TreeNode * left;
    struct TreeNode * right;
 }
struct TreeNode * rebulidTree(char * str,int *pi)
{
    if(str[*pi] == "#")
     {   (*pi)++;
         retrun NULL;
     }
    //构建节点,如果不为空,存入值,继续遍历它的左右子树 
    struct TreeNode * root = (struct TreeNode *)malloc(sizeof(struct TreeNode *));
    
    root->val = str[(*pi)++];
    root->left = rebuildTree(str,pi);
    root->right = rebuildTree(str,pi);
    return root;
}
//中序遍历
  void Inorder(struct TreeNode * root)
    {
        if(root ==NULL)
            return;
        Inorder(root->left);
        printf("%c",root->val)
        Inorder(root->right);
    }
int main()
{
    char str[100];
    scanf("%s",&str);
    int i = 0;
    //先重建这棵树
    struct TreeNode * root = rebuildTree(str,&i);
    Inorder(root);
    return 0;
}

12.判断一棵二叉树是否为平衡二叉树[Leetcode110.]

题目:给定一颗二叉树,判断它是否是高度平衡的二叉树,高度平衡:一个二叉树的每个节点的两个左右子树的高度绝对值不超过1,题目链接:力扣

思路:使用递归,统计它的左右子树,判断左右子树的高度,如果大于1,返回false,如果不大于1,继续遍历它的左右子树,直到root为空。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int TreeHeight(struct TreeNode * root)
{
    if(root ==NULL)
        return 0;
        int leftHeight = TreeHeight(root->left);
        int rightHeight = TreeHeight(root->right);
        return leftHeight > rightHeight ? leftHeight+1 :rightHeight+1;
}

bool isBalanced(struct TreeNode* root){

    if(root ==NULL )
        return true;
    //统计左右子树的高度,左右子树高度的绝对值超过1返回false,否则返回true;
    int left_height = TreeHeight(root->left);
    int right_height = TreeHeight(root->right);
       
    if(abs(left_height -right_height) >1)
        return false;

        return isBalanced(root->left) && isBalanced(root->right);
    return true;

}

 

13.二叉树的层序遍历

        思路:二叉树的层序遍历就是先遍历根节点,然后遍历它的左右子树,遍历完后,再遍历左子树的左右子树,遍历右子树的左右子树。可以使用一个队列,当队列为空的时候,进入根节点,然后出根节点,进入它的左右子树,出根节点,进入左右子树。直到出到队列为空,结束遍历。

        队列之中,如果存二叉树的节点的值,会找不到左右孩子,如果存二叉树的节点,占用空间较多,可以存二叉树的节点指针。代码如下:

void LevelOrder(BTNode * root)
{
    Queue q;
    QueueInit(&q);
    if(root ==NULl)
        return;
    if(root)
        QueuePush(&q,root);
    while(!QueueEmpty(&q))
    {
        BTNode * front = QueueFront(&q);
        print(front->data);
        QueuePop(&q);
        if(front->left)
            QueuePush(&q,front->left);
        if(fornt->right)
            QueuePush(&q,front->right);
     }
}

14.判断一棵树是否为完全二叉树

同样,也是用层序遍历的方法,创建一个队列,如果出的节点是空,后面出的节点不是空,那就不是完全二叉树,如果出空之后后面仍是空,那就是完全二叉树

bool TreeComplete(BTNode * root)
{
    //创建队列
    Queue q;
    QueueInit(&q);
    if(root)
       QueuePush(&q,root);
    while(!QueueEmpty(&q))
    {
        BTNode * front = QueueFront(&q);
        QueuePop(&q)
        if(front ==NULL)
        {
            break;
        }
        
        else
        {
            QueuePush(&q,front->left);
            QueuePush(&q,front->right);
        }
    }
        //break出来判断后面的队列是否为空,如果为空,return true,如果不为空,return false;
        while(!QueueEmpty(&q)
        {
            front = QueuePop(&q);
            if(front != NULL)
                return false;
            Destroy(&q);
            return true;
        }
}

总结

二叉树的相关函数大多用的递归的方法,这个时候需要多画图,理解函数的栈帧,调试看bug。技术有限,如有错误请指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/613019.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis实现分布式锁的原理:常见问题解析及解决方案、源码解析Redisson的使用

0、引言:分布式锁的引出 锁常常用于多线程并发的场景下保证数据的一致性,例如防止超卖、一人一单等场景需求 。通过加锁可以解决在单机情况下安全问题,但是在集群模式下就不行了。集群模式,即部署了多个服务器、并配置了负载均衡后…

记录使用Echarts-gl实现3D地图

一、前言 最近项目需要做个大屏展示的,开始做了第一版用户觉得地图太过于单调了,给我发了一个视频,让我参考着做。我看着视频上的地图旋转了方向、地图有标记、看着像是3D的(视频上的地图使用多个图层叠加起来、CSS样式做了旋转&…

Nginx网络服务——location规则与rewrite重写

Nginx网络服务——location规则与rewrite重写 一、Nginx中location与rewrite1.location与rewrite常用的正则表达式2. location与rewrite的联系和区别 二、location的匹配规则1.location 的匹配分类2.location 常用的匹配规则3.location 优先级4.location匹配规则优先通用的总结…

【知识图谱搭建到应用】--知识存储--04

文章目录 Mysqljenafuseki数据存储数据建模数据映射注意事项 py2neoneo4jPy2neo与Neo4j的版本问题Py2neo导入三元组数据批量导入csv文件 rdflib库 前面几篇在讲述骗理论的内容,本片主要描述如何将清洗过的结构化数据存储在转换成三元组并存储起来,并于后…

ChatGPT与软件架构(4) - 架构师提示工程指南

架构师可以通过各种类型的对话提示,提升驱动ChatGPT对话输出的质量,更好的利用AI能力辅助架构设计。原文: Software Architects’ Guide to Enhancing ChatGPT Interactions With Prompt Types Robert Stump Unsplash 前言 随着ChatGPT等人工智能语言模型…

12.数据结构之AVL树

前言 提到平衡二叉查找树,不得不提二叉查找树。二叉查找树,说简单点,其实就是将我们的数据节点,有序的维护为一个树形结构。这样我们查的时候,那么我们查找某个节点在不在集合中的时间复杂度实际上就是树的高度。如果…

华为OD机试真题 Java 实现【玩牌高手】【2023 B卷 100分】,附详细解题思路

一、题目描述 给定一个长度为n的整型数组,表示一个选手在n轮内可选择的牌面分数。选手基于规则选牌, 请计算所有轮结束后其可以获得的最高总分数。 选择规则如下: 在每轮里选手可以选择获取该轮牌面,则其总分数加上该轮牌面分…

python笔记 第二章 变量

系列文章目录 第一章 初识python 文章目录 2.1变量2.1.1变量的作用2.1.2定义变量标识符命名习惯使用变量 2.2 认识bugDebug工具Debug工具使用步骤: 2.3 数据类型 2.1变量 目标 变量的作用定义变量认识数据类型 2.1.1变量的作用 变量就是一个存储数据的的时候当前数据所在的…

Java基础——堆和栈、static关键字、静态变量和成员变量的区别

Java程序运行顺序:Java应用程序—虚拟机—操作系统—硬件 Java中栈内存用来存储局部变量和方法调用,堆内存用来存储Java中的对象,成员变量、局部变量、类变量指向的对象都存储在堆内存中。 static关键字: 随着类的加载而加载优先…

ISATAP隧道配置与验证

ISATAP隧道配置与验证 【实验目的】 熟悉IPv6ISATAP隧道的概念。 掌握IPv6和IPv4共存的实现方法。 掌握IPv6 ISATAP地址编址规则。 掌握IPv6 ISATAP隧道的配置。 验证配置。 【实验拓扑】 设备参数如下表所示。 设备 接口 IP地址 子网掩码 默认网关 R1 S0/0 192.…

【内存管理大猫腻:从“越界”到“内存泄漏”应有尽有】

本章重点 什么是动态内存 为什么要有动态内存 什么是野指针 对应到C空间布局&#xff0c; malloc 在哪里申请空间 常见的内存错误和对策 C中动态内存“管理”体现在哪 什么是动态内存 动态内存是指在程序运行时&#xff0c;根据需要动态分配的内存空间。 #include <stdio.h&…

1.链表的实现:不带哨兵

一、链表linked list 1.定义 链表是数据元素的线性集合&#xff0c;其每个元素都指向下一个元素&#xff0c;元素存储上并不连续,链表逻辑连续。 2.分类 ①单向链表&#xff1a;每个元素只知道其下一个元素是谁 ②双向链表: 每个元素知道其上一个元素和下一个元素 ③循环链…

Java - Stream流详解

文章目录 前言 大家好,好久不见了,最近由于实训的影响导致拖更了,在更新这一次估计javaSE基本上就算是完结了,还有一些落下的后面也会补上的,下次见面就是数据结构了 尽情期待吧!那么就让我们步入Stream流的学习吧! 一、Stream流是什么&#xff1f; Stream流是Java 8中的一个…

【openEuler 20.03 TLS编译openGauss2.0.0源码】

openEuler 20.03 TLS编译openGauss2.0.0源码 一、安装环境二、安装前准备二、安装步骤 一、安装环境 项目Value操作系统openEuler 20.03 64bit with ARMopenGauss2.0.0openGauss-third_party2.0.0 二、安装前准备 项目Value购买华为ECS鲲鹏 8vCPU32G 100M/s带宽 openEuler 2…

使用CubeMX配置STM32驱动HC-SR04超声波模块

文章目录 前言1 使用STM32CubeMX初始化代码1.1 时钟配置1.2 设置定时器1.3 触发引脚1.4 串口配置 2 代码编写2.1 添加驱动文件2.2 修改main.c 3 实现效果参考 前言 硬件选择 stm32f103c8t6&#xff08;最小板&#xff09;hc-sr04超声波模块 软件环境 stm32cubeIDE 1.12.1 …

【Linux】TCP网络套接字编程+协议定制+序列化和反序列化

悟已往之不谏&#xff0c;知来者之可追。抓不住的就放手&#xff0c;属于你的都在路上…… 文章目录 一、TCP网络套接字编程1.日志等级分类的日志输出API2.单进程版本的服务器客户端通信3.多进程版本和多线程版本4.线程池版本5.守护进程化的线程池服务器6.三次握手和四次挥手的…

python编程——pycharm的安装与使用

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 本文专栏&#xff1a;python专栏 专栏介绍&#xff1a;本专栏为免费专栏&#xff0c;并且会持续更新python基础知识&#xff0c;欢迎各位订阅关注。 目录 一、python IDLE的使用 二、pycharm的安装与使用 1、…

十分钟带你看懂——Python测试框架之pytest最全讲

pytest特短 pytest是一个非常成熟的全功能的Python测试框架&#xff0c;主要有以下几个特点&#xff1a; 简单灵活&#xff0c;容易上手 支持参数化 能够支持简单的单元测试和复杂的功能测试&#xff0c;还可以用来做selenium/appnium等自动化测试、接口自动化测试&#xff08…

重磅版本发布|三大关键特性带你认识 Milvus 2.2.9 :JSON、PartitionKey、Dynamic Schema

亮点颇多、精彩程度堪比大版本的 Milvus 2.2.9 来啦&#xff01; 随着 LLM 的持续火爆&#xff0c;众多应用开发者将目光投向了向量数据库领域&#xff0c;而作为开源向量数据库的领先者&#xff0c;Milvus 也充分吸收了大量来自社区、用户、AI 从业者的建议&#xff0c;把重心…

非常简单就能理解的 链表带环问题 你也能轻松学会!

文章目录 判断链表是否带环若链表带环找出环的入口其他高频的面试问题 判断链表是否带环 题目描述&#xff1a; 给定一个链表&#xff0c;判断链表中是否有环。 思路&#xff1a; 可以明确的是&#xff1a;若一个链表带环&#xff0c;那么用指针一直顺着链表遍历&#xff0c…