文档算法与数据结构知识点总结.docx
- 文档编号:28313775
- 上传时间:2023-07-10
- 格式:DOCX
- 页数:74
- 大小:3.97MB
文档算法与数据结构知识点总结.docx
《文档算法与数据结构知识点总结.docx》由会员分享,可在线阅读,更多相关《文档算法与数据结构知识点总结.docx(74页珍藏版)》请在冰豆网上搜索。
文档算法与数据结构知识点总结
算法与数据结构知识点总结
(教材:
严蔚敏编著老师:
范丹)
本资料由5432与5434宿舍共同整理,在此感谢其他几位同学的辛苦付出。
水平所限,难免有错误、遗漏之处,敬请谅解,也欢迎向我指出。
标黄色的地方不是在画重点,而是表示没有找到资料是我自己写的,请带着批判的眼光去看:
)另外,有的算法我实在没法排在一页了:
(麻烦大家看的时候将就一下
——国金14学委马玥2015秋
学习目标
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])
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 文档 算法 数据结构 知识点 总结
![提示](https://static.bdocx.com/images/bang_tan.gif)