1 基本命令
查看:
show databases;
show tables;
创建:
create database basename charset utf8;
删除:
drop database basename;
建表语句:
create table stu(
snum int,
sname varchar(10)
)engine myisam charset utf8;
寻光之旅
排序:重新排列表中元素,使表中元素满足按关键字递增或递减的过程
算法的稳定性:关键字相同的不同元素排序前后前后相对顺序不变,称该算法是稳定的
内部排序:排序期间元素全存放在内存的排序
外部排序:排序期间元素需要在内外存之间移动的排序
排序思想:序列分为有序部分和无序部分,每次排序将无序部分的一个元素加入有序部分进行排序,重复上述步骤直到全部排序完成。1
2
3
4
5
6
7
8
9void InsertSort(Elemtype A[],int n){
int i,j;
for(i=2;i<=n;i++){ //依次将A[2]到A[n]插入到已排序序列
A[0]=A[i]; //A[0]为哨兵
for(j=i-1;A[j].key>A[i].key&&;j--) //若前驱元素大于A[i】,将其后移一位
A[j+1]=A[j];
A[j+1]==A[0]; //插入A[i]
}
}
算法时间复杂度:O(n2);
算法空间复杂度:O(1);
稳定性:稳定
算法思想:利用折半查找在有序序列中查找目标元素的插入位置,再一次性移动元素后插入目标元素。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20void InsertSort(Elemtype A[],int n){
it i,j,low,mid,high;
for(i=2;i<=n;i++){ //依次将A[2]到A[n]插入到已排序序列
A[0]=A[i]; //A[0]存储待排序元素
low=1;
high=i-1;
while(low<=high){ //查找插入位置
mid=(low+high)/2;
if(A[mid].key>A[0].key)
high=mid-1;
else low=mid+1;
}
for(j=i-1;j>-high+1;j--) //移动元素
A[j+1]=A[j];
A[high+1]=A[0] //插入元素
}
//为什么插入位置是A[high+1]
//可以这样理解:【特例】当源序列有序时,元素插入位置为原来位置,即A[high+1]
}
算法思想:直接插入排序中,排序元素取的步长为1,即比较时是A[i]和A[i+1]进行比较;而希尔排序中取得步长为di(di取值:1= < di <=(n/2)),每一轮排序后将步长减小,直到di=1这一轮排序完成则全部排序完成。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16void ShellSort(Elemtype A[],int n){
int di=n/2;
for(di;di>=1;di=di/2){ //每轮排序后步长减半
int i;
for(i=di+1;i<=n;i++){ //从A[i+di]开始进行直接插入排序
A[0]=A[i];
if(A[i]<A[i-di]){ //判断已排序的最后元素大于欲排序元素,再排序,否则不予排序
int j;
for(j=i-di;j>0;j--){ //后移
A[j+di]=A[j];
}
A[j+di]=A[0]; //插入
}
}
}
}
最坏时间复杂度:O(n2);
稳定性:不稳定
根据序列中两个元素关键字的比较结果决定是否交换两个元素的位置的排序称为交换排序
1 | void BubbleSort(Elemtype A[],int n){ |
时间复杂度:O(n2)
稳定性:由于A[i]=A[j]时不会发送交换,所以为稳定排序。
算法思想:取待排序列中一元素pivot作为基准,经过一趟快速排序确定pivot的最终位置,并划分出大于等于pivot的部分和小于等于pivot的部分;再对每个子序列重复上述过程,直到每一部分只含一个或0个元素,则排序完成。
一趟快速排序1
2
3
4
5
6
7
8
9
10
11
12
13int Partition(Elemtype A[],int low,int high){
Elemtype pivot = A[low];
while(low<hight){
while(low<high&&A[high]>pivot)
high--;
A[low]=A[high];
while(low<high&&A[low]<pivot)
low++;
A[high]=A[low];
}
A[low]=pivot;
return low;
}
快排1
2
3
4
5
6
7void QuickSOrt(Elemtype A[],int low,int high){
if(low<high){
int partition=Partition(A,low,high);
QuickSOrt(A,low,partition-1);
QuickSOrt(A,partition+1,high);
}
}
空间复杂度:快排算法为递归算法,需要借助递归工作栈;其空间复杂度为栈的深度,其平均值为O(log2n)。
时间复杂度:O(n2)
选择排序算法思想:每趟排序选择未排序元素中关键字最小的元素,将其加入到已排序序列的末尾。
1 | void SelectSort(Elemtype A[],int n){ |
时间复杂度:O(n2)
稳定性:交换元素期间会打乱原来含有相同关键字的元素的顺序,不稳定。
堆排序是一种树形选择排序方式,序列L[1]到L[n]经过堆排序后的结构符合完全二叉树的顺序存储结构。
其严格定义为:n个关键字序列L[1…n]称为堆,当且仅当:
1.L[i]<=L[2i] && L[i]<=L[2i+1] (小顶堆) 或
2.L[i]>=L[2i] && L[i]>=L[2i+1] (大顶堆)。
堆排序算法思想:
1 | void BuildMaxHeap(Elemtype A[],int len){ |
堆排序算法:1
2
3
4
5
6
7void HeapSort(Elemtype A[],int len){
BuildMaxHeap; //建大顶堆
for(int i=len;i>1;i--){ //从大到小进行len-1趟排序
Swap(A[len,A[1]]); //交换堆顶元素和堆顶元素
AdjustDown(A,1,i-1) //对剩余元素进行调整使其成堆
}
}
堆排序算法性能:
空间复杂度:O(1)
时间复杂度:O(nlog2n)
稳定性:不稳定
归并排序是将两个或者两个以上的有序序列合并为一个新的有序表1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26Elemtype *B=(Elemtype *)malloc(sizeof(Elemtype)*(n+1))
void Merge(Elemtype A[],int low,int mid,int high){
//表A[low...mid]和A[mid+1...high]分别有序,将它们合并为一个表
for(int i=low;i<=high;i++){ //将A复制给B
B[i]=A[i];
}
int i,j;
for(i=low,j=mid+1,k=i;i<=mid&&j<=high;k++){ //将两分表中值小的复制到A中,下标后移
if(B[i]<=B[j])
A[k]=B[i++];
else
A[k]=B[j++];
}
while(i<=mid) A[k++]=B[i++]; //加入剩余元素
while(j<=high) A[k++]=B[j++];
}
void MergeSort(Elemtype A[],int low,int high){
if(low<high){
int mid=(low+high)/2;
MergeSort(A,low,mid);
MergeSort(A,mid+1;high);
Merge(A,low,mid,high);
}
//递归边界为low=high,此时将不进行操作
}
时间复杂度:O(nlog2n)
稳定性:稳定
基数排序是基于关键字各位的大小进行排序的,基数排序分为最高位(MASD)优先和排序和最低位优先(LSD)排序。
排序步骤(以LSD为例):第一趟排序时只考虑最低位,第二趟排序时只考虑次低位,以此进行n轮排序直到首位也完成排序则基数排序完成。在每趟排序时不进行比较,而是将其放入到已知的容器中,之后再将元素直接按照所在容器的顺序首尾相连,得到一趟排序的结果。,
时间复杂度:每趟排序时有n个元素要进行入队列(队列数目为r)的操作,之后需要连接这r个队列,操作次数为(n+r);设元素共有d位,则需要进行d趟排序,故时间复杂度为O(d*(n+r))。
空间复杂度:需要r个队列,故为O(r)。
算法 | 最好时间复杂度 | 平局时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
直接插入排序 | O(n) | O(n2 ) | O(n2) | O(1) | 是 |
希尔排序 | O(1) | 否 | |||
简单选择排序 | O(n2 ) | O(n2 ) | O(n2 ) | O(1) | 否 |
冒泡排序 | O(n) | O(n2 ) | O(n2 ) | O(1) | 是 |
快速排序 | O(nlog2n) | O(n2) | O(n2) | O(log2n) | 否 |
堆排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(1) | 否 |
2-路归并排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(n) | 是 |
基数排序 | O(d(n+r)) | O(d(n+r)) | O(d(n+r)) | O(r) | 是 |
1 | typedef struct{ //查找表的数据结构 |
查找成功的平均查找长度:(n+1)/2;
查找不成功时的平均查找长度:n+1;
折半查找又称为二分查找,仅适用于有序的顺序表。
算法思想:将key与表中间元素比较,若相对查找 成功;若不等,则依据大小关系往前半部分或后半部分查找;如此重复。1
2
3
4
5
6
7
8
9
10
11
12
13int Binary_Search(SeqList L,ElemType key){
int low=0;high=L.TableLen-1;mid;
while(low<=high){
mid=(low+high)/2;
if(L.elem[mid]==key) //找到则返回
return mid;
else if(L.elem[mid]>key) //往前找
high=mid-1;
else //往后找
low=mid+1;
}
return -1; //找不到返回-1
}
时间复杂度:O(log2n);
分块查找基本思想:将查找表分成若干子块,块间有序而块内元素无序。建立索引表,索引表的内容是:各块的最大关键字和该块的第一个元素地址的映射关系。
查找步骤:先用顺序查找或折半查找确定块,再在块内查找。
B树又称为多路平衡查找树,m阶B树或为空树或满足以下特性:
m阶B+树满足:
散列函数:把查找表中的关键字映射到该关键字对应的地址的函数称为散列函数,记为Hash(key)=Addr。
冲突:散列函数中把两个或以上的关键字映射到同一地址。
散列表:存储关键字和存储地址的直接映射关系。
散列表的查找效率取决于:散列函数、冲突处理方法和填装因子。
填装因子:填装因子=(表中记录数)/(散列表长度)
图G由顶点集V和边集E组成,记为G=(V,E),V非空。
1 | BSTNode *BST_Serach(BiTree T,ElemType key){ |
树是N(N>=0)个结点的有限集合,N=0时,称为空树。任意一棵非空树满足:
树具有以下特点:
数据类型
数据类型是一组值的集合和定义在此集合上一组操作的总称。
抽象数据类型(ADT)
抽象数据类型是一个数学模型和定义在该模型上的一组操作。
抽象数据组成:
* 数据对象
* 数据关系
* 基本操作集
数据结构
结构是指数据之间的相互关系。
数据结构是指相互之间存在特定关系的数据元素的集合。
数据结构构成:
* 逻辑结构
* 存储结构
* 数据的运算
数据的逻辑结构
逻辑结构是指数据之间的逻辑关系。
数据逻辑结构分类:
- 线性结构:
- 一般线性表
- 受限线性表:
- 栈和队列
- 数组
- 线性表推广:
- 广义表
- 非线性结构:
- 集合
- 树形结构
- 图状结构
数据的存储结构
数据的存储结构是指数据结构在计算机中的表示(映像),也称为物理结构。
数据存储结构分类:
算法是对特定问题求解步骤的一种描述。算法有五个重要特征。
算法目标:
时间复杂度
一个语句的频度指该语句在算法中被重复执行的次数,算法中所有语句的频度之和为T(n),T(n)与算法中的基本运算的频率f(n)同数量级。
算法的时间复杂度记为:
空间复杂度
算法的空间复杂度指算法所耗费的存储空间。
算法的就地工作是指算法所需存储空间为常量。即空间复杂度为O(1)
CS模型中客户是服务请求方,服务器是服务提供方,其工作流程是:
- 服务器处于接收请求的状态
- 客服机发出服务请求,等待接收结果
- 服务器收到请求后分析请求并处理,将结果发送给客户机
C/S模型特点:
- 网络中主机地位不平等,服务器拥有更高权限,可以对客户机进行限制
- 客户机之间不直接通信
- 可扩展性不佳,服务器支持的客户机数量有限
在P2P模型中,任意一对计算机称为对等方(Peer),直接相互通信,每个结点即作为服务器也作为客户机。
P2P模型的优点:
- 减轻服务器计算压力,消除对某个服务器的完全依赖
- 多个客户机之间直接共享文档
- 可扩展性好
- 网络健壮性强
DNS系统用于将域名转换为IP地址
域名可以发分为顶级域名、二级域名、三级域名等,其中最高级别的域名写在最右边。
域名解析是把域名映射为IP地址(正向解析)或把IP地址映射为域名(反向解析)的过程,DNS请求以UDP数据报的形式发送。
域名解析有两种方式:
- 递归查询:对根域名负载过大,集合不使用,类似于深度遍历
- 递归和迭代相结合的查询:迭代查询类似于层次遍历
递归与迭代相结合的查询方式:
- 主机向本地域名服务器的查询采用递归查询
- 本地域名服务器向根域名服务器的查询采用迭代查询
FTP是使用最广泛的文件传输协议,FTP屏蔽了计算机系统的异构细节,适合于异构网络中的计算机之间传送文件,FTP采用C/S模型,并使用TCP的可靠传输服务。
FTP提供以下服务:
- 不同主机系统之间的文件传输
- 以用户权限管理的方式提供用户对远程FTP服务器上文件的管理能力
- 以匿名FTP的方式提供公用文件共享的能力
FTP的工作步骤:
- 打开服务器21端口
- 等待客户进程发起连接请求
- 启动从属进程处理客户机请求,客户进程请求处理完毕则从属进程终止
- 回到等待状态,继续接收其他客户进程请求
FTP在工作时使用两个并行的FTP连接:控制连接(21端口)和数据连接(22端口)
控制连接
控制连接用来传输控制信息,如连接请求和传送请求
数据连接
数据连接用来连接客户端和服务端的数据传送进程
电子邮件是一种异步通信方式,发件人将邮件发送到收件人的邮件服务器,收件人可随时上网使用自己的邮件服务器进行读取。
电子邮件组成:
邮件收发过程:
电子邮件格式
首部:
From:abc@gmail.com
To:xyz@gmail.com
Subject:HelloWorld主体:
the content of this email
STMP(简单邮件传输协议)是一种提供可靠有效的电子邮件传输的协议,STMP用TCP连接,使用25端口号。
STMP通信过程:
POP(邮局协议)是一个简单的邮件读取协议,POP3是它的第三版。POP3采用‘拉’(Pull)的通信方式,当用户读取邮件时,UA向邮件服务器发出请求,‘拉’取用户邮箱中的邮件。
POP3也使用C/S的工作方式,在传输层使用TCP,端口是110。
万维网内核部分构成:
万维网工作流程:
HTTP协议规定在服务器和浏览器之间的请求和响应的格式和规则,是万维网进行可靠文件交换的重要基础。
HTTP的操作过程(以访问菜鸟教程为例)
1. 浏览器分析URL(http://www.runoob.com/html/html-intro.html)
2. 浏览器向DNS请求解析www.runoob.com
3. 域名DNS解析百度服务器的IP地址
4. 浏览器与该服务器建立TCP连接(端口号80)
5. 浏览器发送HTTP请求:GET /html/html-intro.html
6. 服务器通过HTTP响应把文件html-intro.html发送给浏览器
7. TCP连接释放
8. 浏览器将文件html-intro.html进行释放,并把Web页面显示给用户
HTTP协议的特点
1. HTTP协议是无状态协议,服务器不会记得曾经访问过的用户,通常采用Cookie来跟踪用户活动。
2. HTTP采用TCP作为运输层协议,但HTTP协议本身是无连接的,双方在交换HTTP报文之前不需要建立连接,
3. HTTP的非持久连接中,对每一个网页元素都需要建立一个TCP连接。
4. HTTP的持久连接中(HTTP/1.1支持)中,同一客户与服务器只需建立一个TCP连接
5. 持久连接分为流水线方式和非流水线方式,非流水线方式中,客户在收到一个响应前不能再发送下一个请求;流水线方式中,客户可以连续发送请求。
HTTP的报文结构
HTTP报文分为请求报文和响应报文
请求报文:
- 请求行:包含方法、URL和HTTP版本
- 首部行:
- 实体主体:通常不用
响应报文:
- 状态行:包含版本、状态码和短语
- 首部行:
- 实体主体:可能没有
HTTP请求报文中的常见方法:
方法 | 意义 |
---|---|
GET | 请求读取由URL所标志的信息 |
HEAD | 请求读取由URL所标志的信息的首部 |
POST | 给服务器添加信息 |
CONNECT | 用于代理服务器 |
应用程序 | FTP数据链路 | FTP控制链路 | TENNET | SMTP | DNS | TFTP | HTTP | POP3 | SNMP |
---|---|---|---|---|---|---|---|---|---|
使用协议 | TCP | TCP | TCP | TCP | UDP | UDP | TCP | TCP | TCP |
端口 | 20 | 21 | 23 | 25 | 50 | 69 | 80 | 110 | 161 |