数据结构 顺序表1
1. 何为顺序表:
顺序表是一种线性数据结构,是由一组地址连续的存储单元依次存储数据元素的结构,通常采用数组来实现。顺序表的特点是可以随机存取其中的任何一个元素,并且支持在任意位置上进行插入和删除操作。在顺序表中,每个元素的下标都是唯一的,而且在顺序表中,相邻的元素在内存中也是相邻的。
顺序表通常包含两个重要的属性:容量和长度。容量指该顺序表所能容纳的最大元素数量,而长度指当前已经存储的元素数量。当长度等于容量时,顺序表就已经满了,不能再插入元素。
2. 静态顺序表和动态顺序表的区别:
由于顺序表底层是用数组完成的,所以这个数组决定了我们这个顺序表的大小,同时也区分出了静态顺序表与动态顺序表,下面我们来一一了解:
静态顺序表:有着静态两字顾名思义则这个顺序表写好以后大小就固定死了,是不可以改变的(为了方便我们后期更改顺序表的类型,此处我们define定义一个变量,专门存放顺序表类型)
typedef int SLDataTYpe;typedef struct SeqList
{SLDataTYpe p[50]; //数组大小为50,代表这个顺序表可以存储50个元素int size; //顺序表有效数据个数int capacity; //顺序表空间大小
}SL; //将顺序表struct SeqList取别名为SL
动态顺序表:相较于静态,动态顺序表则在定义顺序表是写死数据的大小,而是定义了一个指针,等到后边需要用到顺序表的时候,再动态分配内存空间(C语言动态内存空间分配-CSDN博客)
typedef int SLDataTYpe;typedef struct SeqList
{SLDataTYpe* p;int size; //顺序表有效数据个数int capacity; //顺序表空间大小
}SL; //将顺序表struct SeqList取别名为SL
3. 顺序表的实现:
在本次项目当中我们以动态顺序表为例,来对顺序表各类功能的实现,项目文件分为SeqList.h(顺序表中各类函数的声明),SeqList.c(顺序表各类功能的实现),SeqList_test(对应顺序表各类功能的测试),实现环境为VS2022
3.1. 顺序表的初始化:
在SeqList.h声明一个函数用于实现顺序表的初始化,同时传入一个顺序表变量,SeqList.c实现顺序表的初始化,顺序表没被调用前,顺序表为NULL(注:要想调用SeqList.h中声明好的方法,则得包含该方法所在的头文件)
SeqList.h:
#pragma once
#include <stdio.h>
typedef int SLDataTYpe;//动态顺序表
typedef struct SeqList
{SLDataTYpe* p;int size; //顺序表有效数据个数int capacity; //顺序表空间大小
}SL; //将顺序表struct SeqList取别名为SL//顺序表的初始化
void SLInit(SL* ps);
SeqList.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h" //头文件包含//顺序表初始化的实现
void SLInit(SL* ps)
{ps->p = NULL; ps->size = 0; //有效数据个数为0ps->capacity = 0; //空间大小为0
}
SeqList_test(在SeqList_test中调用SLInit函数,打开监视查看是否赋值成功):
void SLTest01()
{SL s1;SLInit(&s1);}int main()
{SLTest01();return 0;
}
测试结果:
(如上图所示,则初始化成功)
3.2. 顺序表的销毁:
顺序表的销毁分为两种情况,一是顺序表已写入数据,二是没有写入数据
SeqList.h:
#pragma once
#include <stdio.h>
typedef int SLDataTYpe;//动态顺序表
typedef struct SeqList
{SLDataTYpe* p;int size; //顺序表有效数据个数int capacity; //顺序表空间大小
}SL; //将顺序表struct SeqList取别名为SL//顺序表的初始化
void SLInit(SL* ps);//顺序表的销毁
void SLDesttroy(SL* ps);
SeqList.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"//顺序表初始化的实现
void SLInit(SL* ps)
{ps->p = NULL;ps->size = 0;ps->capacity = 0;
}//顺序表的销毁
void SLDesttroy(SL* ps)
{if (ps->p) //判断是否为NULL{free(ps->p);}ps->p = NULL;ps->size = 0;ps->capacity = 0;
}
(由于代码量的缘故,后边只展示对应文件中要添加的代码)
3.3. 顺序表插入数据:
为了方便展示,关于SeqList.h文件当中的代码,统一展示在此处
//顺序表头部插入删除 / 尾部插入删除
void SLPushBack(SL* ps, SLDataTYpe x);
void SLPushFront(SL* ps, SLDataTYpe x);void SLPopBack(SL* ps);
void SLPopFront(SL* ps);//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataTYpe x);//删除指定位置数据
void SLErase(SL* ps, int pos);
3.3.1. 头插:
头插可以分为以下几点:
1. 函数传参:
void SLPushFront(SL* ps, SLDataTYpe x); //x为要插入的元素
2. 判断顺序表是否为空:
#include <assert.h> //头文件包含
assert(ps); //ps为要断言的变量
3. 判断顺序表空间是否够用:
由于后续我们要多次判断是否要增容,此处我们重新用一个函数完成顺序表的增容:
(注:realloc函数如果申请内存空间失败,则返回NULL,所以此处不可将realloc申请的空间直接赋给p->p这样会导致原来p->p中的数据全部清空,应先判断增容是否成功,再进行赋值)
void SLcheckCapacity(SL* p)
{//插入数据前判断空间是否足够 如果数组大小与内存总大小相等,则申请空间if (p->size == p->capacity){//判断capacity的值是否为0,不为0则2倍增容int newcapacity = p->capacity == 0 ? 4 : 2 * p->capacity;//增容空间SLDataTYpe* tmp = (SLDataTYpe*)realloc(p->p, 2 * newcapacity * sizeof(SLDataTYpe));//判断增容是否成功if (tmp == NULL){perror("relloc fail");exit(1);}//申请成功以后p->p = tmp;p->capacity = newcapacity;}
}
4. 头部插入数据:
假设一个数组中已有数据a,b,c,d,现在要在头部添加一个元素f,我们应该如何添加?
思路分析:
代码实现(SeqList.c):
void SLPushFront(SL* ps, SLDataTYpe x)
{//判断ps是否为NULLassert(ps);//判断内存空间是否足够,是否需要增容SLcheckCapacity(ps);//将顺序表中原有的数据整体往后挪一位for (int i = ps->size; i > 0; i--){ps->p[i] = ps->p[i - 1];}//添加元素ps->p[0] = x;//size向后挪动一位ps->size++;
}
3.3.2. 尾插:
假设一个数组中已有数据a,b,c,d,现在要在最后添加一个元素f,我们应该如何添加?
思路分析:
代码实现(SeqList.c):
void SLPushBack(SL* ps, SLDataTYpe x)
{//判断ps是否为NULLassert(ps);//判断内存空间是否足够,是否需要增容SLcheckCapacity(ps);ps->p[ps->size++] = x;}
3.3.3 头删:
将除首地址的元素外其余所以元素往前挪动一位,同时size也需往前挪动一位(size--),覆盖首元素即可(注:如果数组中没有元素,即size=0,此时是没有元素可以删的,所以此处应还需断言size是否为0)
思路分析:
代码实现(SeqList.c):
void SLPopFront(SL* ps)
{//判断ps是否为NULLassert(ps);//判断数组是否为空assert(ps->size);for (int i = 0; i < ps->size - 1; i++){ps->p[i] = ps->p[i + 1];}ps->size--;
}
3.3.4 尾删:
当数组不为空时,size往前挪一位(注size代表的是数组的大小,即下标+1,也就是说size前边为整个数组,因此删除末尾元素时,我们只需要将size--即可)
思路分析:
代码实现(SeqList.c):
void SLPopBack(SL* ps)
{//断言assert(ps);//判断顺序表是否为NULL,为空删除等于-1,越界assert(ps->size);//删除数据ps->size--;
}
3.3.5 指定位置添加数据:
与头插相类似,此处只需要将指定位置的数据整体往后挪一位size++,由于和头插相类似,就不在此处重复直接看代码:
void SLInsert(SL* ps, int pos, SLDataTYpe x)
{assert(ps);assert(pos >= 0 && pos <= ps->size); //判断pos的有效范围//插入数据:空间够不够SLcheckCapacity(ps);//让pos下标对应的数据,全部往后挪一位for (int i = ps->size; i > pos; i--){ps->p[i] = ps->p[i - 1];}ps->p[pos] = x;ps->size++;}
3.3.6 指定位置删除数据:
与添加相反,删除指定对应数据以后,指定位置后的元素整体往前挪一位,size--
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);for (int i = pos; i < ps->size - 1; i++){ps->p[i] = ps->p[i + 1];}ps->size--;
}
3.4 顺序表的打印:
遍历数组
代码实现(SeqList.h / SeqList.c):
//顺序表的打印
void SLPrintf(SL s);
void SLPrintf(SL s)
{//打印for (int i = 0; i < s.size; i++){printf("%d ", s.p[i]);}printf("\n");
}
3.5 顺序表的查找:
遍历数组,查找对应的元素,存在返回元素的下标,不存在返回无效下标-1
代码实现(SeqList.h / SeqList.c):
//查找
int SLFind(SL* ps, SLDataTYpe x); //数据有,返回值的下标,否则返回-1
查找
int SLFind(SL* ps, SLDataTYpe x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->p[i] == x){//找到了return i;}}//没找到return -1;
}
4.实现代码:
SeqList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDataTYpe;
//动态顺序表
typedef struct SeqList
{SLDataTYpe* p;int size; //顺序表有效数据个数int capacity; //顺序表空间大小
}SL;//顺序表的初始化
void SLInit(SL* ps);//顺序表的销毁
void SLDesttroy(SL* ps);//顺序表头部插入删除 / 尾部插入删除
void SLPushBack(SL* ps, SLDataTYpe x);
void SLPushFront(SL* ps, SLDataTYpe x);void SLPopBack(SL* ps);
void SLPopFront(SL* ps);//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataTYpe x);//删除指定位置数据
void SLErase(SL* ps, int pos);//顺序表的打印
void SLPrintf(SL s);//查找
int SLFind(SL* ps, SLDataTYpe x); //数据有,返回值的下标,否则返回-1
SeqList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"//顺序表初始化的实现
void SLInit(SL* ps)
{ps->p = NULL;ps->size = 0;ps->capacity = 0;
}//顺序表的销毁
void SLDesttroy(SL* ps)
{if (ps->p){free(ps->p);}ps->p = NULL;ps->size = 0;ps->capacity = 0;
}//增容
void SLcheckCapacity(SL* p)
{//插入数据前判断空间是否足够 如果数组大小与内存总大小相等,则申请空间if (p->size == p->capacity){//判断capacity的值是否为0int newcapacity = p->capacity == 0 ? 4 : 2 * p->capacity;//增容空间SLDataTYpe* tmp = (SLDataTYpe*)realloc(p->p, 2 * newcapacity * sizeof(SLDataTYpe));//判断增容是否成功if (tmp == NULL){perror("relloc fail");exit(1);}//申请成功以后p->p = tmp;p->capacity = newcapacity;}
}//顺序表的尾插
void SLPushBack(SL* ps, SLDataTYpe x)
{//判断ps是否为NULLassert(ps);SLcheckCapacity(ps);ps->p[ps->size++] = x;}//头插
void SLPushFront(SL* ps, SLDataTYpe x)
{//判断ps是否为NULLassert(ps);//增容SLcheckCapacity(ps);//将顺序表中原有的数据整体往后挪一位for (int i = ps->size; i > 0; i--){ps->p[i] = ps->p[i - 1];}ps->p[0] = x;ps->size++;
}//顺序表的打印
void SLPrintf(SL s)
{//打印for (int i = 0; i < s.size; i++){printf("%d ", s.p[i]);}printf("\n");
}//尾删
void SLPopBack(SL* ps)
{//断言assert(ps);//判断顺序表是否为NULL,为空删除等于-1,越界assert(ps->size);//删除数据ps->size--;
}//头删
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);for (int i = 0; i < ps->size - 1; i++){ps->p[i] = ps->p[i + 1];}ps->size--;
}//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataTYpe x)
{assert(ps);assert(pos >= 0 && pos <= ps->size); //判断pos的有效范围//插入数据:空间够不够SLcheckCapacity(ps);//让pos下标对应的数据,全部往后挪一位for (int i = ps->size; i > pos; i--){ps->p[i] = ps->p[i - 1];}ps->p[pos] = x;ps->size++;}//删除指定位置数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);for (int i = pos; i < ps->size - 1; i++){ps->p[i] = ps->p[i + 1];}ps->size--;
}//查找
int SLFind(SL* ps, SLDataTYpe x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->p[i] == x){//找到了return i;}}//没找到return -1;
}
SeqList_test.c(测试代码)
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"void SLTest01()
{SL s1;SLInit(&s1);}int main()
{SLTest01();return 0;
}
尾插
//SLPushBack(&s1, 1);
//SLPushBack(&s1, 2);
//SLPushBack(&s1, 3);
//SLPushBack(&s1, 4);
//SLPrintf(s1);
//SLPushBack(&s1, 5);
//SLPrintf(s1);
//SLPushFront(&s1, 5);
//SLPushFront(&s1, 6);
//SLPrintf(s1);
//
//
销毁
//SLDesttroy(&s1);
(有需要的小伙伴自取喔,最后还请点赞三联支持一下博主,Thanks♪(・ω・)ノ!!!)
相关文章:

数据结构 顺序表1
1. 何为顺序表: 顺序表是一种线性数据结构,是由一组地址连续的存储单元依次存储数据元素的结构,通常采用数组来实现。顺序表的特点是可以随机存取其中的任何一个元素,并且支持在任意位置上进行插入和删除操作。在顺序表中…...
C++基础-编程练习题1
文章目录 一、哥德巴赫猜想二、哥德巴赫猜想2三、打印成绩单四、成绩输入输出五、数组输出奇数位偶数位 一、哥德巴赫猜想 【试题描述】 哥德巴赫提出了以下的猜想:任何一个大于 2 的偶数都可以表示成 2 个质数之和。 质数是指除了 1 和本身之外没有其他约数的数&a…...

四十九坊股权设计,白酒新零售分红制度,新零售策划机构
肆拾玖坊商业模式 | 白酒新零售体系 | 新零售系统开发 坐标:厦门,我是易创客肖琳 深耕社交新零售行业10年,主要提供新零售系统工具及顶层商业模式设计、全案策划运营陪跑等。 不花钱开3000多家门店,只靠49个男人用一套方法卖白酒…...

如何将公众号添加到CSDN个人主页
1. 创作中心- 推广管理 输入个人公众号名字并开启微信公众号推广 2. 将公众号的二维码图片加入拓展信息 个人主页的左下角就能看到推广 如果希望能看到是二维码 操作如下: 写篇文章贴上二维码 然后点击鼠标右键获得此页面链接 ,例如我的个人公众号 htt…...
64K方法数限制原理及解决方案
64K限制的原因 Android APK文件本质上是一个压缩文件,它包含的classes.dex文件是可执行的Dalvik字节码文件,这个.dex文件中存放的就是编译后的Java代码。Dalvik可执行文件规范限制了单个.dex文件最多引用的方法数是65536个。其中包含联网Android Framew…...

产品品牌CRUD
文章目录 1.renren-generator生成CRUD1.数据库表设计1.数据表设计2.分析 2.代码生成器生成crud1.查看generator.properties(不需要修改)2.修改application.yml 连接的数据库修改为云数据库3.启动renren-generator模块4.浏览器访问 http://localhost:81/5…...

惠普发布全新AI战略,重塑办公空间 引领企业智能化新浪潮
近日、全球知名科技公司惠普在北京隆重举办了以“用智能,开启无限可能”为主题的2024惠普商用AI战略暨AI PC新品发布会,此次盛会标志着惠普在人工智能领域迈出了重要一步,惠普紧跟时代步伐,推出了更高效、更安全、更灵活的AI PC产…...

python中的数据可视化:极坐标散点图
【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 python中的数据可视化: 极坐标散点图 [太阳]选择题 关于以下代码输出结果的说法中正确的是? import matplotlib.pyplot as plt import numpy as np n 150 r 2 * np.r…...

5.12.1 Detecting and classifying lesions in mammograms with Deep Learning
计算机辅助检测 (CAD) 系统的开发是为了帮助放射科医生分析筛查性乳房 X 光检查,深度 CNN 有可能彻底改变医学图像分析。我们提出了一种基于最成功的对象检测框架之一 Faster R-CNN 的 CAD 系统。该系统无需任何人为干预即可检测乳房 X 光照片上的恶性或良性病变并对…...

Python爬虫——如何使用urllib的HTTP基本库
怎样通过 urllib库 发送 HTTP 请求? urllib库主要由四个模块组成: urllib.request 打开和读取 URLurllib.error 包含 urllib.request 抛出的异常urllib.parse 用于解析 URLurllib.robotparser 用于解析 robots.txt 文件 1. 使用urllib.parse解析URL 使用urlparse(…...

OceanBase v4.3特性解析:新功能“租户克隆”的场景与应用指南
熟悉或曾用过OceanBase的朋友,对于“多租户”这一理念定不陌生。OceanBase的租户概念,与我们熟知的传统数据库实例颇为相似。举例来说,OceanBase的租户支持MySQL兼容模式,对于用户而言,选用一个MySQL兼容模式的租户&am…...

RS3236-3.3YUTDN4功能和参数介绍及PDF资料
RS3236-3.3YUTDN4功能和参数介绍及PDF资料-公司新闻-配芯易-深圳市亚泰盈科电子有限公司 品牌: RUNIC(润石) 封装: XDFN-4-EP(1x1) 描述: 带过温保护 输出类型: 固定 最大输入电压: 7.5V 输出电压: 3.3V 最大输出电流: 500mA RS3236-3.3YUTDN4 是一款低压差线性稳压器&#x…...
Vue如何引入公用方法
文章目录 1. 在全局范围内引入2. 在单文件组件中引入3. 使用Vuex或Vue Composition API4. 使用mixins5. 使用插件 1. 在全局范围内引入 在你的main.js或main.ts文件中引入并注册你的公用方法,使得它们可以在整个Vue应用中使用。 // 引入你的公用方法文件 import {…...

Java面试题:ConcurrentHashMap
ConcurrentHashMap 一种线程安全的高效Map集合 jdk1.7之前 底层采用分段的数组链表实现 一个不可扩容的数组:segment[] 数组中的每个元素都对应一个HashEntry数组用以存放数据 当放入数据时,根据key的哈希值找到对应的segment数组下标 找到下标后就会添加一个reentrantlo…...

现在闪侠惠递寄快递有福利了,千万不要因没把握住而后悔呀!
闪侠惠递平台寄快递现在真的是太便宜了,优惠价格把握不住,后悔都来不及!大家可以在闪侠惠递上面寄快递,价格真的非常优惠呢,比咱们平常寄快递的价格都优惠呢,真的,小编都亲自替大家尝试过了呢。…...

vue+ant-design+formBuiler表单构建器——技能提升——form design——亲测有效
最近看到后端同事在弄一个后台管理系统,额,前端真的是夹缝中生存啊,AI抢饭碗,后端也想干前端的活儿。。。 他用到了表单构建器,具体效果如下: 网上有很多适用于ElementUi和ant-design的form design插件,下…...

Git 如何管理标签命令(tag)
1.查看本地仓库tag --1.查看本地仓库tag UserDESKTOP-2NRT2ST MINGW64 /e/GITROOT/STARiBOSS/STARiBOSS-5GCA (gw_frontend_master) $ git tag 1stBossUpgrade V10.0.1_20220224_test V10.0.1_20220301_test tag-gwfrontend-V1.0.12-230625 tag-gw_frontend-23.08.29 tag-gw_f…...

零样本身份保持:ID-Animator引领个性化视频生成技术新前沿
在最新的研究进展中,由Xuanhua He及其团队提出的ID-Animator技术,为个性化视频生成领域带来了突破性的创新。这项技术的核心在于其零样本(zero-shot)人物视频生成方法,它允许研究者和开发者根据单一的参考面部图像生成…...
在Go语言中,可以这样使用Json
在Go语言中,处理JSON数据通常涉及编码(将Go结构体转换为JSON字符串)和解码(将JSON字符串转换为Go结构体)。Go标准库中的encoding/json包提供了这些功能。第三方插件可以使用"github.com/goccy/go-json"也有同…...

React useEffect Hook: 理解和解决组件双重渲染问题
在React中,useEffect可能会在组件的每次渲染后运行,这取决于它的依赖项。如果你发现useEffect运行了两次,并且你正在使用React 18或更高版本的严格模式(Strict Mode),这可能是因为在开发模式下,…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...