肝了一个月,全网最全的数据结构与算法知识总结
在线脑图:https://www.processon.com/view/link/617aa00f07912943dd03d4f4
开发环境
Mac C语言环境配置
软件:Visual Studio Code
Coder Runner 插件 :目的是为了实现在Visual Studio Code中 运行C语言代码
一、数据结构的概述
1、定义
我们如何把现实中大量而复杂的问题以
特定的数据类型
和特定的存储结构
保存到主存储器(内存)当中,以及在此基础上为实现某个功能(比如查找某个元素,删除某个元素,对所有元素进行排序)而执行的相应操作,这个相应的操作也叫算法
狭义:
数据结构是专门研究数据存储问题
数据的存储包含两方面:个体的存储+个体关系的存储
广义:
数据结构既包含数据的存储也包含数据的操作
对存储数据的操作就是算法
数据结构 = 个体 + 个体的关系
算法 = 对存储数据的操作
2、算法
什么是算法?
广义:算法是对存储对象的操作
狭义:指的是解决问题的方法和步骤
解题的方法和步骤
如何衡量算法的标准?
1、时间复杂度:程序大概要执行的次数,而非执行的时间
2、空间复杂度:算法执行过程中大概所占用的最大内存
3、难易程度
4、健壮性
3、数据结构的地位?
数据结构是软件中最核心的课程
程序 = 数据的存储 + 数据的操作 + 可以被计算机执行的语言
4、数据存储有几种结构?
1、线性结构
连续存储【数组】
优点:存储速度快
缺点:插入删除元素时很慢
空间有限制
事先必须知道数组的长度
需要大块连续存储块
离散存储【链表】
- 优点:空间无限制
- 缺点:存储速度慢
线性结构的应用----【栈】
线性结构的应用----【队列】
2、非线性结构
- 树
- 图
二、预备知识
1、指针
(1)、指针的重要性:C语言的灵魂
(2)、定义:
- 地址:
- 内存的存储编号(门牌号)
- 从0开始的非负整数
- 范围:0 --> FFFFFFFFF【0-4G-1】
- 指针:
- 指针就是地址,地址就是指针
- 指针变量是存放内存单元的地址的变量
- 指针的本质是一个操作受限的非负整数
2、结构体
(1)为什么会出现结构体?
为了表达一些复杂的数据,普通的基本类型变量无法满足要求,结构体由此诞生!
(2)什么叫结构体
结构体是用户根据我们实际需要可自己定义的复合数据类型
(3)注意事项:
3、动态内存的分配和释放
4、递归
一、递归原理分析
(1)递归的定义
(2)分治法
(3)函数调用过程
(4)递归与栈
用阶层问题分析递归与栈
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RWriEn7a-1636795139579)(https://tva1.sinaimg.cn/large/008i3skNgy1gvypqofp7kj31600u0gry.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8iHFRanF-1636795139580)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyptu8i2qj31l60r6n13.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o76SwMmF-1636795139581)(https://tva1.sinaimg.cn/large/008i3skNgy1gvypvc0qdhj31pk0tedkq.jpg)]
二、相关应用
(1)求阶层
#include<stdio.h>
// 求n的阶层
long getJC(long n){if(n==1){return 1;}else{return getJC(n-1) * n;}}
int main(){printf("result=%ld",getJC(20));return 0;
}
(2)1+2+3+…+100的和
#include<stdio.h>
// 求1到100的和
long getSum(long n){if(n==1){return 1;}else{return getSum(n-1) + n;}}
int main(){printf("sum=%ld",getSum(100));return 0;
}
(3)走迷宫
(4)汉诺塔
函数的调用
当一个函数的运行期间调用另一个函数,在运行背调函数之前,系统需要完成三件事:
1)、将所有的实际参数
,返回地址
等信息发送给被调函数
2)、 为被调函数的局部变量(也包括形参)分配内存空间
3)、将控制转移动到被调函数的入口,分配空间
从被调函数返回主调函数,系统也要完成三件事:
1)、保存被调函数的返回结果
2)、释放被调函数所占的存储空间
3)、依照被调函数保存的返回地址
将控制转移到主调函数的地方
递归的应用
数和森林就是以递归的方式定义的
数和图的很多算法都是以递归来实现的
很多数学公式都是以递归的方式来定义的
三、线性结构
什么是线性结构?
可以用一根线把所有节点串起来,否则为非线性结构(树、图)
1、顺序表
(1)什么叫数组?
元素类型相同,大小相等
(2)数组的优缺点?
自创数组
#include<stdio.h>
#include<mm_malloc.h>
#include<stdlib.h> // 包含了exit();
/*模拟数组
*/// 定义了一个数据类型,该数据类型的名字叫struct Arr,含有三个成员,分别是pBase,len,cnt
struct Arr{int *pBase; // 存储的是数组第一个元素的地址int len; // 数组所能容纳的最大元素个数int cnt; // 当前数组有效元素的个数
};/*
所有声明
*/
void initArr(struct Arr *pArr, int length);
bool isEmpty(struct Arr *pArr);
void showArr(struct Arr *pArr);
bool appendArr(struct Arr *pArr ,int val);
bool insertArr(struct Arr *pArr ,int pos,int val);
bool isFull(struct Arr *pArr);
bool deleteArr(struct Arr *pArr ,int pos,int *pVal);
void inversionArr(struct Arr *pArr);
void softArr(struct Arr *pArr);/*
主函数
*/
int main(){// int val;// 用于接收删除元素的值struct Arr arr; // 定义一个变量arr,目前没有内容initArr(&arr,6);// printf("%d\n",arr.len);// showArr(&arr);// printf("\n---------------------\n");// appendArr(&arr,1);// appendArr(&arr,2);// appendArr(&arr,3);// appendArr(&arr,4);// appendArr(&arr,5);// appendArr(&arr,6);// appendArr(&arr,7);// showArr(&arr);// printf("\n---------------------\n");// insertArr(&arr,6,99);// showArr(&arr);// 测试deleteArr()// appendArr(&arr,1);// appendArr(&arr,2);// appendArr(&arr,3);// appendArr(&arr,4444);// appendArr(&arr,5);// appendArr(&arr,6);// showArr(&arr);// printf("\n---------------------\n");// deleteArr(&arr,4,&val); // val为用于接受所删除数据的值// printf("被删的元素值为:%d\n",val);// showArr(&arr);// 实现倒置// appendArr(&arr,1);// appendArr(&arr,2);// appendArr(&arr,3);// appendArr(&arr,4);// appendArr(&arr,5);// appendArr(&arr,6);// inversionArr(&arr);// showArr(&arr);// printf("\n---------------------\n");// 实现升序排序printf("\n---------------------\n");appendArr(&arr,2);appendArr(&arr,7);appendArr(&arr,5);appendArr(&arr,4);appendArr(&arr,8);appendArr(&arr,3);softArr(&arr);showArr(&arr);return 0;}/*初始化
*/
void initArr(struct Arr *pArr, int length){pArr->pBase = (int *)malloc(sizeof(int) * length); //pArr 这个指针变量所指向的那个结构体变量中的pBaseif(NULL == pArr->pBase){printf("动态内存分配失败!\n");exit(-1); // 终止挣个程序}else{pArr->len = length; // 数组所能容纳的最大元素个数pArr->cnt = 0;}return;
}/*显示输出
*/void showArr(struct Arr *pArr){if(isEmpty(pArr)){printf("数组为空\n");}else{for (int i = 0; i < pArr->cnt; i++){printf("%d ",pArr->pBase[i]); printf("\n");}}
}/*判断数组是否为空
*/
bool isEmpty(struct Arr *pArr){if (0 == pArr->cnt){return true;}else{return false;}
}/*追加
*/
bool appendArr(struct Arr *pArr ,int val){// 满了 不能追加if(isFull(pArr)){return false;}// 不满的时候可以追加 : 1、 流程 2、功能 3、试错pArr->pBase[pArr->cnt] = val;pArr->cnt++;return true;
}
/*判断是否已满
*/
bool isFull(struct Arr *pArr){if(pArr->len == pArr->cnt){printf("已满\n");return true;}else{return false;}
}bool insertArr(struct Arr *pArr ,int pos,int val){// 1、判断是否已满,如果已满则不能插入if(isFull(pArr)){return false;}// 2、再判断是否越界if(pos <1 || pos>pArr->cnt+1){return false;}for(int i = pArr->cnt-1; i>=pos-1; i--){pArr->pBase[i+1] = pArr->pBase[i]; // 把最后一个 给 最后一个的下一个}pArr->pBase[pos-1] = val; // 插入pArr->cnt++; // 有效个数加1return true;
}bool deleteArr(struct Arr *pArr ,int pos,int *pVal){if(isEmpty(pArr)){printf("数组为空\n");return false;}if(pos<1 && pos>pArr->cnt){printf("范围异常");return false;}// 先找到这个值*pVal = pArr->pBase[pos-1];// 开始删除for(int i = pos; i<pArr->cnt; i++){pArr->pBase[i-1] = pArr->pBase[i];}pArr->cnt--;// 有效个数减1return true;
}void inversionArr(struct Arr *pArr){int i=0; //第一个int j=pArr->cnt-1; // 最后一个int temp;while (i<j) // 值互换{ temp = pArr->pBase[i];pArr->pBase[i] = pArr->pBase[j];pArr->pBase[j] = temp;i++;j--;}return;}void softArr(struct Arr *pArr){// 选择排序int temp;for(int i =0; i<pArr->cnt; i++){for(int j=i+1; j<pArr->cnt;j++){if(pArr->pBase[i]>pArr->pBase[j]){temp = pArr->pBase[i];pArr->pBase[i] = pArr->pBase[j];pArr->pBase[j] = temp;}}}}
2、链表
预备知识-typedef关键词
目标:手敲链表
1、
#include<stdio.h>
typedef int QQ; //为int 从新多去一个名字 int = QQ
typedef struct Student{int sid;char name[100];char sex;
}St; // St 等同于struct Studentint main(){int i = 10;QQ j = 10; // QQ等同于intprintf("%d %d",i,j);struct Student st;struct Student *ss;St st; // St st 等价于 struct Student st;St *ss; // St *ss等价于struct Student *ss;return 0;
}
2、
#include<stdio.h>typedef struct Student{int sid;char name[100];char sex;
}*St; // *St 等同于struct Student *int main(){ return 0;
}
3、
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3X8vxHbp-1636795139582)(https://tva1.sinaimg.cn/large/008i3skNgy1guxvs7qj1ej61j70u0gp702.jpg)]
(1)定义
1、N个节点离散的
2、彼此通过指针项链
3、每一个节点只可能有一个前驱节点,每个节点后面只可能有一个后驱节点。收节点没有前驱节点,尾结点没有后驱节点
专业术语:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3FrZlmm2-1636795139582)(https://tva1.sinaimg.cn/large/008i3skNgy1guxwgf3wunj61h00c440f02.jpg)]
**首节点 :**第一个有效节点
**尾结点:**最后一个有效节点
头结点:第一个有效节点之前的节点
头结点并不存放有效数据
加头结点的目的主要是为了方便对链表的操作
头结点的数据类型和首结点一样
**头指针:**指向头结点的指针变量
**尾指针:**指向尾结点的指针变量
我们确定一个链表需要几个参数????
只需要一个参数:头指针,因为我们通过头指针可以推算出链表的其他所有信息
(2)分类
1、单链表
2、双链表:每一个节点有两个指针
3、循环链表:能通过任何一个节点找到其他所有的节点
4、非循环链表:
(3)算法
算法有两个标准,一个是广义的,一个是狭义的,从狭义的讲,算法跟数据的存储是有关系的,广义的讲,则
是无关的。
泛型:
利用某种技术达到的效果就是:不同的存储方式,执行的操作是一样的
注:狭义与广义区别
- 狭义:从内部的真正实现上说
- 广义:
怎么学算法?
涉及数学相关,把答案拿出来,把答案看懂!
如何将一个程序(答案)由不懂到看懂?
- 流程
- 每个语句的功能
- 试错
1、遍历
2、查找
3、清空
4、销毁
5、求长度
6、排序
7、删除节点
…
自创链表
#include<stdio.h>
#include<mm_malloc.h>typedef struct Node{int data; //数据域struct Node *pNext;
}NODE,*PNODE;//声明函数
PNODE create_list();
void traverse_list(PNODE pHead);
bool is_empty(PNODE pHead);
int getLenght(PNODE pHead);
bool insert_list(PNODE pHead,int pos,int val);
bool deleteList(PNODE pHead,int pos,int *val); // 第三个参数用于存储被删链表的数值
void softList(PNODE pHead); //排序
bool insertList(PNODE pHead,int pos,int val); //链表插入 ,pos从1开始
bool deleteList(PNODE pHead,int pos,int *pVal); int main(){PNODE pHead = NULL; // 等价于struct Node *pHead = NULL;pHead = create_list(); //create_list()功能: 创建一个非循环单链表,并将该链表的头结点的地址赋给pHeadtraverse_list(pHead);//traverse_list 遍历输出if (is_empty(pHead)){printf("链表为空!\n");}else{printf("链表不为空!\n");}int len = getLenght(pHead);printf("链表长度为:%d\n",len);printf("\n-------------\n");//测试排序// softList(pHead);// traverse_list(pHead);printf("\n-------------\n");//测试插入// insertList(pHead,4,520);// traverse_list(pHead);printf("\n-------------\n");//测试删除int val;if (deleteList(pHead,4,&val)){printf("删除成功,该元素的值为:%d\n",val);}else{printf("删除失败,您好删除的元素不存在\n");}traverse_list(pHead);return 0;}PNODE create_list(){// 分配了一个不存放有效数据的头结点PNODE pHead = (PNODE)malloc(sizeof(NODE));// if(NULL == pHead){printf("分配失败,程序终止!");exit(-1);}PNODE pTail = pHead;pTail->pNext = NULL;int len;int i; // 用来存放用户有效输入节点的个数int val; // 用来临时存放用户输入的节点的值printf("请输入您需要生成链表节点的个数:len=");scanf("%d",&len);for(i=0; i<len; i++){printf("请输入第%d个节点的值:",i+1);scanf("%d",&val);PNODE pNew = (PNODE)malloc(sizeof(NODE));if(NULL == pHead){printf("分配失败,程序终止!");exit(-1);}pNew->data=val;// 将生成的节点挂到pHead头指针上,如何挂?方法如下pTail->pNext = pNew;pNew->pNext = NULL;pTail = pNew;// pTail指向将pNew所在结构体对象的地址}return pHead;
}void traverse_list(PNODE pHead){// 遍历输出PNODE p = pHead->pNext;while (p!= NULL){printf("%d ",p->data);p = p->pNext;}printf("\n");return;
}bool is_empty(PNODE pHead){if (pHead->pNext==NULL){return true;}else{return false;}}int getLenght(PNODE pHead){int len = 0;// 遍历输出PNODE p = pHead->pNext;while (p!= NULL){len++;p = p->pNext;}return len;
}// bool insert_list(PNODE pHead,int pos,int val);//冒泡排序/**/
void softList(PNODE pHead){int i,j;int temp;int len =getLenght(pHead);PNODE p,q;for (i=0,p=pHead->pNext; i<len-1; i++,p=p->pNext) // 外层循环,6个数,只需要比较5次{for(j=i+1,q=p->pNext; j<len; j++,q=q->pNext){if(p->data>q->data){ //类使用数组中a[i]>a[j]temp = p->data;p->data =q->data;q->data = temp;}}}return;
}// 在pHead所指向链表的第pos个节点的前面插入一个新的节点,该节点的值为val,并且pos的值是从1开始
bool insertList(PNODE pHead,int pos,int val){//pos的范围是否合法int i = 0;PNODE p = pHead;while (p!=NULL && i <pos-1) //这个循环的目的是让p指向pos的前面一个节点{p = p->pNext; // 最终p会指向i++;}if (p==NULL || i >pos-1){return false;}PNODE pNew = (PNODE)malloc(sizeof(NODE));if(NULL == pNew){printf("分配失败,程序终止!");exit(-1);}pNew->data=val; //值存入//开始插入PNODE q = p->pNext; //q为中间变量p->pNext = pNew;pNew->pNext=q;return true;/*这三行为核心代码-详细分析可以看下方流程图PNODE q = p->pNext; //q为中间变量p->pNext = pNew;pNew->pNext=q;*/
}bool deleteList(PNODE pHead,int pos,int *pVal){//pos的范围是否合法int i = 0;PNODE p = pHead;while (p->pNext!=NULL && i <pos-1) //这个循环的目的是让p指向pos的前面一个节点{p = p->pNext; // 最终p会指向i++;}if (NULL==p->pNext || i >pos-1){return false;}//接受被删除节点所存储的数值*pVal = p->pNext->data;//开始删除PNODE q = p->pNext; // 先将要删除的元素存起来,以便后面释放空间p->pNext = p->pNext->pNext; // 所谓删除,就是将p指向要删除的元素的后面一个,然后将p的空间释放free(p);}
插入3行代码分析:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7VmcoK1w-1636795139583)(https://tva1.sinaimg.cn/large/008i3skNgy1guyrsvusnij617g0u00wh02.jpg)]
(4)循环链表
定义:一种头尾相连的链表(即:表中最后一个节点的指针域指向头结点,整个链表形成了一个环)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-82Q801CB-1636795139584)(https://tva1.sinaimg.cn/large/008i3skNgy1gvycbjmuluj31gc0aa0th.jpg)]
==优点:==从表中的任一节点出发都能找到表中其他节点。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ih5KKsSA-1636795139585)(https://tva1.sinaimg.cn/large/008i3skNgy1gvych8gfkoj31pi0rwwip.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-deD3G3Ll-1636795139586)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyciyb3j1j31ax0u0q7e.jpg)]
如何将带尾指针的两个循环链表合并?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S6JhcwTX-1636795139587)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyclyczpdj31660fs0ue.jpg)]
分析一下有哪些操作?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qDSC5XZZ-1636795139587)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyct7jw4kj31bi0i0dhx.jpg)]
(1)、先保留Ta的头结点:p = Ta->next
(2)、将Ta表的表尾接到Tb表的第一个有效节点:Ta->next =Tb->next->next;
(3)、释放Tb表的头结点:free(Tb->next);delete Tb->next;
(4)、Tb表的尾结点指向Ta表的头结点:Tb->next =p
(5)双向链表
1、定义:在单链表的每个节点里增加一个指向其直接前驱的指针域prior,这样链表中形成了有两个方向不同的链,故称为双向链表。
2、结构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QkmgIcrY-1636795139588)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyd16o0n2j31l60j60ve.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3nG0iPH3-1636795139589)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyd4yzum8j31pa0d6gmn.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-12rWf49i-1636795139590)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyd5eoncbj31dm094jsk.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-riEDNJhO-1636795139590)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyd5t4xirj30ug0aamxh.jpg)]
双向链表的插入
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lWnqpPgi-1636795139591)(https://tva1.sinaimg.cn/large/008i3skNgy1gvye28l89dj31at0u0q5s.jpg)]
(6)双向循环链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qcAxoKSy-1636795139592)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyd75zg84j31o40lm77m.jpg)]
(7)顺序表与链表的比较
一、链表的优缺点:
优点:
1、节点空间可以动态申请和释放
2、删除和插入操作的时候只需要修改指针,而不需要移动元素
缺点:
3、存储密度小,原因是每个节点在存储数据本身的同时,还需要额外的存储它的后续节点和前驱节点的地址,占用的空间比较大
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rSqLIwNC-1636795139592)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyegifr3dj31b20iu76f.jpg)]
4、非随机存取结构,时间复杂度就提高了
什么是随机存取?
即:任意一个元素都可以通过下表获取到
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Obb5F049-1636795139593)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyekqhwkzj31g20u0wmp.jpg)]
(8)线性表的应用
1、线性表的合并
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Wb3SmXr-1636795139594)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyeqy4httj31ou0f2mzi.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2dVmhRGH-1636795139594)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyhx6j83kj30yg0fswg0.jpg)]
实现方式:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zzJIY7og-1636795139595)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyi11kel3j31c60oodm6.jpg)]
2、有序线性表的合并
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w8XxypXY-1636795139596)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyes2xdiuj31ne0fegos.jpg)]
为什么是非递减有序排序?
因为可能存在重复元素
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RYvBi7Ql-1636795139597)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyi4u8vdkj31me0fugoi.jpg)]
顺序表实现有序表的合并:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2PZv55Uk-1636795139598)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyi8sloxjj31p60oo0zg.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9xy2qUKA-1636795139598)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyibbvnmsj31oe0o6dkq.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F3NErfLZ-1636795139599)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyicrsbz1j31fw04i0tr.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZgUkE5RB-1636795139600)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyidi138nj31em04cgmo.jpg)]
链表实现有序表合并
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fwjGttbK-1636795139601)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyilzayzej31ku0okn02.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hl4f9jMC-1636795139601)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyimqglvxj31ne0tadk7.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YLPVSulo-1636795139602)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyin3hwiqj31j40s40vw.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rOUIOxMg-1636795139603)(https://tva1.sinaimg.cn/large/008i3skNgy1gwbctsxtv1j31me0r841w.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2lIx6uEZ-1636795139604)(https://tva1.sinaimg.cn/large/008i3skNgy1gvyirvueagj31kc04u0ty.jpg)]
注:最坏情况就是La和Lb一样长,所有的都要执行完,所有时间复杂度是最大为
肝了一个月,全网最全的数据结构与算法知识总结相关推荐
- 【硬核】肝了一个月,Cisco网络工程师知识点总结
[硬核]肝了一个月,Cisco网络工程师知识点总结 高能预警,本文是我一个月前就开始写的,所以内容会非常长,当然也非常硬核,有实验,有命令,所以才写到了现在. 我相信90%的读者都不会一口气看完的,因 ...
- 肝了一个月,整理了一万道2020年最新Java面试题,阿里offer有了
肝了一个月的面试题终于来啦,大家开心不. 2020年最新Java面试题整理,全网最全一份,包含各个技术栈,Java基础,Java集合,多线程,Java异常,spring,spring MVC,spri ...
- 全网最全json数据结构可视化工具汇总
全网最全json数据结构可视化工具汇总 1.前言 2. 可视化工具 2.1 JSON Viewer Pro(推荐) 2.2 JSONGrid(推荐) 2.3 json2html(推荐) 2.4 Onl ...
- 肝了一个月,我做了个免费的面试刷题网
大家好,我是鱼皮. 如今找工作.面试实在是太卷了,每轮面试都 必考 八股文,不背不行.网上虽然有很多面试题,但过于分散,就导致很多朋友又不知道到哪去找题.该背哪些题了. 所以我决定做一个完全免费.干净 ...
- 肝了一个月,终于搞到了 30 页的 Python 进阶面试题
聚焦国内外,各个企业都在广泛应用 Python.国外例如谷歌.NASA.YouTube.Facebook.工业光魔和红帽等:国内大厂有阿里.腾讯.豆瓣.搜狐.新浪.网易.百度.金山.盛大.热酷.土豆以 ...
- 我肝了一个月,给你写出了这本 Java 开发手册!
作者 | cxuan 来源 | 程序员cxuan 超长预警!!全文4万多字,墙裂建议收藏! 先来看一下本篇文章的思维导图吧,我会围绕下面这些内容进行讲解.内容很干,小伙伴们看完还希望不吝转发. 下面开 ...
- 肝了一个月!这本 Java 开发手册出炉啦!
大家好,我是久一. 今天推送一篇高质量博文,这篇文章一共 44330 字,超级全面的 Java 基础知识总结,图文并茂.如果需要 PDF 版本的,可以后台回复「开发手册」下载!作者是久一的好朋友 cx ...
- 肝了一个月的 DDD,一文带你掌握!
整体阅读时间,在 30 分钟左右. 大家好,我是楼仔! 去年倒腾了一个半月,写过一篇 DDD 的文章,当时没有推广,完全自嗨,为了不让这篇好文被埋没,现重新整理,突出重点,可读性更强! 为了证明该文没 ...
- 肝了一个月的 DDD,一文带你掌握
整体阅读时间,在 30 分钟左右. 大家好,我是楼仔! 去年倒腾了一个半月,写过一篇 DDD 的文章,当时没有推广,完全自嗨,为了不让这篇好文被埋没,现重新整理,突出重点,可读性更强! 为了证明该文没 ...
- 我肝了一个月,给你写出了这本Java开发手册。
先来看一下本篇文章的思维导图吧,我会围绕下面这些内容进行讲解. 下面开始我们的文章. Java 概述 什么是 Java? Java 是 Sun Microsystems 于1995 年首次发布的一种编 ...
最新文章
- 吉大c语言程序设计作业一,吉林大学历年C语言程序设计试题及答案.doc
- android+4.4+img,重新打包boot.img时出错(Android)
- tensorflow官网视频教程
- python的自带数据集_解决Keras自带数据集与预训练model下载太慢问题
- 信息系统项目管理师一些重要问题和知识点
- 极光尔沃切片软件_极光尔沃3D打印机走进肥东中小学校
- 今天才知道,MySQL 的 binlog 编号可以这么大!
- linux添加物理卷编辑文件夹,Red hat Linux下的逻辑卷管理器LVM-上
- Nginx应用场景之动静分离
- python:ValueError: numpy.ufunc size changed, may indicate binary incompatibility. Expected 216 from
- 蓝桥杯 省赛 杨辉三角形 python组(转)
- rdkit GetAtoms获取化合物每个位置的索引;rdkit FindMCS大公共相同结构 找不同化合物之间的差异
- 伪原创文章实操方式。
- Python掷骰子游戏
- 微软五笔 v1.0 下载
- 微软2008年7月「最有价值专家」(MVP)当选名单
- oracle 动态声明变量_Oracle11g新特性之动态变量窥视
- 【转】ORA-28040: 没有匹配的验证协议
- 晨光科力普基于GitLab CI/CD持续集成服务的应用
- 数据结构之冒泡排序算法(图解+分析+代码调优)