算法与数据结构知识点总结.docx

上传人:b****5 文档编号:6944200 上传时间:2023-01-12 格式:DOCX 页数:64 大小:3.97MB
下载 相关 举报
算法与数据结构知识点总结.docx_第1页
第1页 / 共64页
算法与数据结构知识点总结.docx_第2页
第2页 / 共64页
算法与数据结构知识点总结.docx_第3页
第3页 / 共64页
算法与数据结构知识点总结.docx_第4页
第4页 / 共64页
算法与数据结构知识点总结.docx_第5页
第5页 / 共64页
点击查看更多>>
下载资源
资源描述

算法与数据结构知识点总结.docx

《算法与数据结构知识点总结.docx》由会员分享,可在线阅读,更多相关《算法与数据结构知识点总结.docx(64页珍藏版)》请在冰豆网上搜索。

算法与数据结构知识点总结.docx

算法与数据结构知识点总结

算法与数据结构知识点总结

 

学习目标

1.熟练掌握基本的数据结构

2.理解相关操作的算法实现

3.掌握算法的复杂度分析方法

4.领会从数据结构的设计和实现角度优化解决实际问题的思想

相关术语&基础知识

1.数据、数据元素

数据:

对客观事物的符号表示,所有能输入到计算机中并被计算机程序处理的符号的总称。

数据元素:

组成数据的、具有意义的基本单位,计算机中通常作为整体处理。

2.数据项

组成数据的不可分割的最小单位

3.数据对象

性质相同的数据元素的集合,是数据的子集

4.逻辑结构

数据对象中数据元素之间的逻辑关系;是从操作对象抽象出来的数学模型

5.物理结构(存储结构)

数据元素逻辑关系在计算机中的表示(映像);包括数据元素的表示和逻辑关系的表示;关系到数据操作的实现

6.数据类型

数据类型是一个值的集合和定义在这个值集上的一组操作的总称。

7.抽象数据类型(ADT)

是指一个数据模型以及定义在该模型上的一组操作。

三要素:

数据元素、逻辑关系、操作

8.算法的设计原则

正确性、可读性、健壮性、高效率与低存储量

9.算法效率的度量

10.常见结构的时间复杂度★

(1)顺序结构O

(1)

(2)分支结构O

(1)

(3)循环结构的时间复杂度=循环体内语句的频度(重复执行次数)

11.时间复杂度的计算

时间复杂度的简化求解步骤

step1.定位最深层循环

step2.由内向外逐层计算循环体的执行频度

step3.只保留最高阶项

step4.去掉最高阶项系数

得到的结果即为时间复杂度的大O阶。

 

12.时间复杂度的大小关系★

13.影响空间复杂度的因素

(1)程序本身所占空间

(2)输入数据所占空间

(3)辅助变量所占空间

若输入数据所占空间只取决于问题本身,和算法无关,则只需要分析除输入和程序之外的辅助变量所占额外空间。

对知识掌握的四种程度

1.了解:

选择题

2.理解:

知道原理,题里可能有拐弯的地方

3.掌握:

算法语句填空

4.熟练掌握:

整...个...算...法...

PS:

以下,“要求”会展开详细内容;若无必要,“考点”不展开详细内容。

一、线性表

考点:

1.线性表的逻辑结构和各种存储表示方法

2.定义在逻辑结构上的各种基本运算(知道名字即可)

InitList(*L)

操作结果:

初始化一个空的线性表L。

DestroyList(*L)

初始条件:

线性表L已经存在。

操作结果:

销毁线性表L。

ClearList(*L)

初始条件:

线性表L已经存在。

操作结果:

将L清空为空表。

ListEmpty(L)

初始条件:

线性表L已经存在。

操作结果:

若L为空返回true,否则返回false。

ListLength(L)

初始条件:

线性表L已经存在。

操作结果:

返回线性表L的元素个数。

GetElem(L,i,*e)

初始条件:

线性表L已经存在,i∈[1,ListLength(L)]。

操作结果:

将L中第i个位置的元素返回给e。

LocateElem(L,e,compare())

初始条件:

线性表L已经存在。

操作结果:

在L中查找与给定值e满足关系compare()的元素,无参数compare()默认为相等关系,找到后返回其第一个元素的位序,查找失败返回0。

ListInsert(L,i,e)

初始条件:

线性表L已经存在,i∈[1,ListLength(L)+1]。

操作结果:

在L中第i个位置插入新元素e,L的长度加1。

ListDelete(L,i,*e)

初始条件:

线性表L已经存在且非空,i∈[1,ListLength(L)]。

操作结果:

删除L中第i个位置元素,并用e返回其值,L的长度减1。

3.在各种存储结构上如何实现这些基本运算

4.各种基本运算的时间复杂性

要求:

1.理解两种存储结构各自的特点、优缺点、适用范围

2.熟练掌握顺序表和单链表上建表、插入、删除、查找操作的算法实现及相关的复杂度分析

⑴顺序表

①建表

StatusListCreat(SqList*L)/*从屏幕逐位读入数据生成顺序表*/

{

intn,i;

printf("请输入顺序表L的数据个数:

\n");

scanf("%d",&n);

if(n>MAXSIZE)

{

printf("\n数据个数过长,请不要超过%d!

\n",MAXSIZE);

returnERROR;

}

elseif(n<0)

{

printf("\n输入不合法\n");

returnERROR;

}

for(i=0;i

{

printf("data[%d]=",i);

scanf("%d",&((*L).data[i]));

}

(*L).length=n;

printf("\n");

returnOK;

}

时间复杂度:

O(n)

②插入

/*初始条件:

线性表L已经存在,i∈[1,ListLength(L)]*/

/*操作结果:

将L中第i个位置插入新元素e,L长度加1*/

intListInsert{SqListL,inti,ElemTypee}

{

intk;

if(L.length==MAXSIZE)/*顺序表已满*/

returnERROR;

if(i<1||i>L.length+1)/*i不合法*/

returnERROR;

if(i<=L.length)/*插入位置不在表尾*/

{

for(k=L.length–1;k>=i-1;k--)

L.data[k+1]=L.data[k];/*从后向前逐位后移*/

}

L.data[i-1]=e;/*插入新元素e*/

L.length++;

returnOK;

}

时间复杂度:

最好O

(1)最坏O(n)平均O(n)(依赖于插入位置i、表长n)

③删除

/*初始条件:

线性表L已经存在,i∈[1,ListLength(L)]*/

/*操作结果:

将L中第i个位置元素删除,并用e返回该元素的值,L长度减1*/

intListDelete{SqListL,inti,ElemType*e}

{

intk;

if(L.length==0)/*顺序表为空*/

returnERROR;

if(i<1||i>L.length)/*i不合法*/

returnERROR;

*e=L.data[i-1];/*用e返回删除元素的值/

if(i

{

for(k=i;k

L.data[k-1]=L.data[k];/*删除位置后继元素逐一前移*/

}

L.length--;

returnOK;

}

时间复杂度:

最好O

(1)最坏O(n)平均O(n)(依赖于插入位置i、表长n)

④查找(按位获取操作)

#defineOK1

#defineERROR0

/*初始条件:

线性表L已经存在,i∈[1,ListLength(L)]*/

/*操作结果:

将L中第i个位置的元素返回给e*/

intGetElem{SqListL,inti,ElemType*e}

{

if(L.length==0||i<1||i>L.length)

returnERROR;

*e=L.data[i-1];

returnOK;

}

时间复杂度:

O

(1)

⑵单链表

①建表

Node*ListCreatTail()/*尾插法建立带头结点的单链表,链表长度为n,链表元素从屏幕读取,返回头结点位置*/

{

LinkListp,r,L;

intn,i;

ElemTyped;

L=(LinkList)newNode;

printf("\n请输入链表L的数据个数:

\n");

scanf("%d",&n);

L->data=n;

L->next=Null;

r=L;

for(i=1;i<=n;i++)

{

p=(Node*)newNode;

printf("结点%d=",i);

scanf("%d",&d);

p->data=d;

p->next=Null;

r->next=p;

r=p;

printf("\nNode%d=%d\n",i,p->data);

}

printf("\n");

returnL;

}

时间复杂度:

O(n)

②插入

链表的插入:

一定,二建,三后,四前

StatusListInsert{LinkListL,inti,ElemTypee}

{

Node*p,*q;

p=GetElem(L,i-1);

if(p==Null)/*链表为空*/

returnERROR;

q=(Node*)malloc(sizeof(Node));

q->data=e;

q–>next=p–>next;

p–>next=q;

returnOK;

}

时间复杂度:

O

(1)

③删除

链表的删除:

一定,二连,三放

StatusListDelete{LinkListL,inti,ElemType*e}

{

Node*p,*q;

p=GetElem(L,i-1);

if(p==Null||p->next==Null)/*链表为空*/

returnERROR;

q=p->next;

*e=q->data;

p–>next=q->next;

free(q);

returnOK;

}

时间复杂度:

O

(1)

④查找

a.按位获取

//链表不是随机存取结构

Node*GetElem{LinkListL,inti}

{

intk;/*k为计数器*/

LinkListp;/*指针p指向当前结点*/

p=L;/*指针p指向头结点*/

k=1;

while(p&&k

{

p=p->next;/*p指向下一个结点*/

++k;/*计数器加1*/

}

if(k==i)/*结点i存在*/

returnp;

else

returnNull;

}

时间复杂度:

最好O

(1)最坏O(n)

b.按值获取

/*初始条件:

线性表L已经存在*/

/*操作结果:

定位L中与给定值相等的元素,返回其位置*/

Node*LocateElem{LinkListL,ElemTypee}

{

LinkListp;/*指针p指向当前结点*/

p=L;/*指针p指向头结点*/

while(p&&p->data!

=e)

p=p->next;/*p指向下一个结点*/

if(!

p)/*结点i不存在*/

returnNull;

else

returnp;

}

时间复杂度:

最好O

(1)最坏O(n)

3.了解双向链表和循环链表的定义和特点及插入、删除操作的实现(见书和PPT)

二、栈和队列

考点:

1.栈和队列的逻辑结构和两种存储表示方法

2.定义在逻辑结构上的各种基本运算

InitStack(&S)

操作结果:

初始化一个空的栈S。

DestroyStack(&S)

初始条件:

栈S已经存在。

操作结果:

销毁栈S。

ClearStack(&S)

初始条件:

栈S已经存在。

操作结果:

将栈S清空。

StackEmpty(S)

初始条件:

栈S已经存在。

操作结果:

若栈S为空返回true,否则返回false。

StackLength(S)

初始条件:

栈S已经存在。

操作结果:

返回栈S的元素个数。

GetTop(S,&e)

初始条件:

栈S已经存在且非空。

操作结果:

将S的栈顶元素返回给e。

Push(&S,e)

初始条件:

栈S已经存在且非空。

操作结果:

新元素e入栈。

Pop(&S,&e)

初始条件:

栈S已经存在且非空。

操作结果:

删除S的栈顶元素,并用e返回其值。

3.在各种存储结构上如何实现这些基本运算

4.各种基本运算的时间复杂性

5.栈的常用应用

要求:

1.理解栈和队列的异同点、栈和队列与一般线性表的不同

2.了解顺序栈的溢出和顺序队列的假溢问题

⑴顺序栈的溢出

①上溢(overflow):

栈满时再压入数据

②下溢(underflow):

栈空时再弹出数据

栈满:

S.top==MAXSIZE–1

空栈:

S.top==–1

3.熟练掌握顺序栈(两栈共享空间)、链栈、循环队列、链队列上的队列初始化、元素插入、删除的算法实现及相关的复杂度分析

⑴顺序栈(两栈共享空间)初始化

StatusInitDuStack(Sqstack&S)

{

S.top1==-1;

S.top2==MAXSIZE;

returnOK;

}

时间复杂度O

(1)

⑵顺序栈(两栈共享空间)元素插入

/*新元素e入栈*/

StatusPush{SqDuStackS,SElemTypee,intStackNum}

{

if(S.top1+1==S.top2)/*栈满*/

returnERROR;

if(StackNum==1)/*新元素压入栈1*/

S.top1++;

S.data[S.top1]==e;/*新元素入栈*/

returnOK;

elseif(StackNum==2)

S.top2--;

S.data[S.top2]==e;/*新元素入栈*/

returnOK;

elsereturnERROR;

}

时间复杂度O

(1)

⑶顺序栈(两栈共享空间)元素删除[来自网络]

//若栈不空,则删除s的栈顶元素,用e返回其值,并返回OK;否则返回ERROR

StatusPop(SqDuStack*S,ElemType*e,intstackNumber)

{

if(stackNumber==1)

{

if(S->top1==1)

returnERROR;//说明栈1已经是空栈,溢出

*e=S->data[s->top1--];//将栈1的栈顶元素出栈

}

elseif(stackNumber==2)

{

if(S->top2==MAXSIZE)

returnERROR;//说明栈2已经是空栈,溢出

*e=S->data[S->top2++];//将栈2的栈顶元素出栈

}

returnOK;

}

时间复杂度O

(1)

⑷链栈初始化[来自网络]

voidInitLinkStack(linkStack&S)

{

       S=newSNode;

       S->next=NULL;

}

时间复杂度O

(1)

⑸链栈元素插入

/*新元素e入栈*/

StatusPush(LinkStack*S,SElemTypee)

{

SNode*p=(SNode*)malloc(sizeof(SNode));/*动态申请结点*/

p->data=e;/*结点赋值*/

p->next=S->top;/*新结点插到表头*/

S->top=p;/*栈顶指针改为新结点*/

S->length++;

returnOK;

}

时间复杂度O

(1)

⑹链栈元素删除

/*栈顶元素出栈*/

StatusPop(LinkStack*S,SElemType*e)

{

StackNode*p;

if(StackEmpty(*S))

returnERROR;

p=S->top;/*p指向出栈结点*/

*e=p->data;/*返回栈顶元素*/

S->top=p->next;/*栈顶指针下移*/

free(p);/*释放结点空间*/

S->length--;

returnOK;

}

(7)循环队列的初始化

/*队列初始化*/

StatusIntiQueue(SqQueue*Q)

{

Q->front=0;

Q->rear=0;

returnOK;

}

/*求队列长度*/

intQueueLength(SqQueueQ)

{

return(Q.rear–Q.front+MAXSIZE)%MAXSIZE;

}

时间复杂度O

(1)

(8)循环队列元素插入

/*新元素e入队列*/

StatusEnQueue(SqQueue*Q,QElemTypee)

{

if((Q->rear+1)%MAXSIZE==Q->front)

returnERROR;/*队满*/

Q->data[Q->rear]=e;/*新元素入队*/

Q->rear=(Q->rear+1)%MAXSIZE;/*rear指针后移,若到最后则转到数组头部*/

returnOK;

}

时间复杂度O

(1)

(9)循环队列元素删除[由书P65修改]

//队头元素出队

Status DeQueue(SqQueue*Q,QElemTypee)

{

if(front==rear)returnERROR;/*队空*/

e=Q->data[Q->front];

Q->front=(Q->front+1)%MAXSIZE;/*front指针后移,若到最后则转到数组头部*/

  returnOK;

  }

(10)链队列的初始化

StatusInitQueue(LinkQueue&Q)

{

Q.front=Q.rear=(QNode*)malloc(sizeof(QNode));

if(!

Q.front)exit(OVERFLOW);

Q.front->next=NULL;

returnOK;

}

时间复杂度O

(1)

(11)链队列的元素插入

//*新元素e入队列*/

StatusEnQueue(LinkQueue*Q,QElemTypee)

{

QNode*p=(QNode*)malloc(sizeof(QNode));/*动态申请结点,C语言*/

//QNode*p=NewQNode;/*动态申请结点,C++*/

if(!

p)/*存储分配失败*/

exit(OVERFLOW);

p->data=e;/*结点赋值*/

p->next=Null;

Q->rear->next=p;/*新结点插到队尾*/

Q->rear=p;/*新结点设置为队尾*/

returnOK;

}

时间复杂度O

(1)

(12)链队列的元素删除

/*队头元素出队列*/

StatusDeQueue(LinkQueue*Q,QElemType*e)

{

QNode*p;

if(Q->front==Q->rear)/*队空*/

returnERROR;

p=Q->front->next;/*p指向要出队元素所在结点*/

*e=p->data;/*用e返回出队元素*/

Q->front->next=p->next;/*头结点指向出队元素的下一个结点*/

if(Q->rear==p)/*出队前只有一个元素*/

Q->rear=Q->front;

free(p);

returnOK;

}

时间复杂度O

(1)

4.了解栈的常用应用,理解利用栈实现递归的原理,掌握逆波兰式的生成和计算

(1)栈的常用应用:

数值转换、括号匹配、算术表达式求解、迷宫求解、实现递归

(2)利用栈实现递归的原理:

见栈和队列3课件

(3)逆波兰式生成和计算

逆波兰表示:

所有的符号都在运算数字后面出现

例:

9+(3–1)*3+10/2中缀表示法

  931–3*+102/+后缀表示法,不再需要括号

计算:

遇到数字就进栈

见到符号就运算

运算结果也进栈

最终结果栈底见

生成:

遇到数字就输出

符号进栈要比较

低级平级都得等

高于栈顶才能进

左边括号等匹配

右括号来了一起闪

三、串

考点:

1.串的逻辑结构和两种存储表示方法

2.堆存储串的基本运算及复杂度分析

3.串的模式匹配

要求:

1.理解串与线性表的不同(数据对象、操作对象)

串:

数据对象:

字符集操作对象:

子串

线性表:

数据对象:

集合操作对象:

线形表

2.掌握串的复制操作的算法及复杂度分析

3.理解串的模式匹配思想及两种基本的模式匹配算法,掌握next数组的计算方法

(1)BruteForce算法——朴素匹配算法

思路:

从主串S第i位开始的m位字符串,依次与T第1位-第m位比较,若相等,返回比较之前的i值;否则i退回,从下一位开始比较;如果从S的所有位开始都不能成功匹配T,返回0.

intIndex(SStringS,SStringT)

{

inti=1,j=1;

while(i<=S[0]&&j<=T[0])

{

if(S[i]==T[j]){i++;j++;}//比较T中下一字符

else{i=i–j+2;j=1;}//i回溯,j回溯,重新开始匹配

}

if(j>T[0])returni-T[0];

elsereturn0;

}

时间复杂度O(m*n)最坏:

m(n-m+1)

(2)KMP算法(克努特—莫里斯—普拉特算法)

思路:

失配时,i不回溯,T尽量多滑动一段距离

intIndex_KMP(SStringS,SStringT)

{

inti=1,j=1;

while(i<=S[

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1