数据结构整理期末复习.docx
- 文档编号:7654612
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:31
- 大小:453.75KB
数据结构整理期末复习.docx
《数据结构整理期末复习.docx》由会员分享,可在线阅读,更多相关《数据结构整理期末复习.docx(31页珍藏版)》请在冰豆网上搜索。
数据结构整理期末复习
数据结构期末复习材料
第一章
1、数据元素之间关系的映像:
(1)顺序映像(顺序存储结构):
以相对的存储位置表示后继关系。
(2)非顺序映像(链式存储结构):
借助指针元素存储地址的指针表示数据元素之间的逻辑关系。
2、ADT定义的方法:
数据对象、结构关系、基本操作。
3、算法的定义:
对特定问题求解步骤的一种描述,它是指令的有限序列,其中每一条指令表示一个或多个操作。
算法的5要素:
有穷性、确定性、可行性、输入、输出
4、算法的评价——衡量算法优劣的标准
正确性(correctness):
满足具体问题的需求
可读性(readability):
易读、易理解
健壮性(robustness):
当输入数据非法时,算法能够做出反应或进行处理
效率与低存储量:
执行时间短、存储空间小
第二章
1、线性表是一种最简单的线性结构。
线性结构是一个数据元素的有序(次序)关系
特点:
存在唯一的一个“第一个”的数据元素;存在唯一的一个“最后一个”的数据元素;除第一个数据元素外,均有唯一的前驱;除最后一个数据元素外,均有唯一的后继。
2、线性表类型的实现——顺序映像定义:
用一组地址连续的存储单元依次存放线性表中的数据元素。
(1)以“存储位置相邻”表示有序对
LOC(ai)=LOC(ai-1)+l其中l是一个数据元素所占存储量
LOC(ai)=LOC(a1)+(i-1)×l
特点:
1、实现逻辑上相邻—物理地址相邻2、实现随机存取
(2)若假定在线性表中任何一个位置上进行插入的概率都是相等的,则移动元素的期望值为:
,时间复杂度为O(n)。
若假定在线性表中任何一个位置上进行删除的概率都是相等的,则移动元素的期望值为:
,时间复杂度为O(n)。
(3)顺序表的插入和删除操作:
StatusListInsert_sq(SqList&L,inti,ElemTypee)
{
//在线性表中第i个元素前插入一个元素
if(i<0||i>L.length)returnERROR;
if(L.length>=L.listsize)
{//当前存储空间已满,增加分配
newbase=(ElemType)realloc(L.elem,
(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if(!
newbase)exit(OVERFLOW);//分配失败
L.elem=newbase;//新基址
L.listsize+=LISTINCREMENT;//增加存储容量
}
q=&(L.elem[i-1]);//q为插入位置
for(p=&(L.elem[L.length-1]);p>=q;--p)
*(p+1)=*p;//元素后移
*q=e;//插入e
++L.length;//表长增1
returnOK
}//ListInsert_sq
StatusListDelete_sq(SqList&L,inti,ElemType&e){
//在线性表中删除第i个元素,并用e返回其值
//i的合法值为1≤i≤L.length
if(i<1||i>L.length)returnERROR;
p=&(L.elem[i-1]);//p为被删除元素的位置
e=*p;//被删除元素的值赋给e
q=&(L.elem[L.length-1]);//q为表尾元素的位置
for(p;p --L.length;//表长减1 returnOK; }//ListDelete_sq 3、线性表类型的实现——链式映像 线性链表特点: 用一组地址任意的存储单元存放线性表中的数据元素。 (1)结构定义 TypedefstructLnode{ ElemTypedata;//数据域 StructLNode*next;//指针域 }Lnode; TypedefstructLinkList{ Lnode*head; }LinkList; (2)插入删除操作 StatusListInsert_L(LinkList&L,inti,ElemTypee){ //在带头结点的单链表中第i个位置前插入元素e p=L->head;j=0;//插入位置可能是第一个元素前,所以 这里指向头结点 while(p&&j if(p->next==NULL||j>i-1)returnError;//i小于1或者大于表长+1 S=(Lnode*)malloc(sizeof(LNode));//生成新结点 s->data=e; s->next=p->next;p->next=s;//插入到L中p之后 returnOK; }//ListInsert_L StatusListDelete_L(LinkList&L,inti,ElemType&e){ //在带头结点的单链表中删除第i个结点,并由e返回其值 p=L->head;j=0; while(p->next&&j //寻找第i个结点,令p指向其前驱 p=p->next;++j; } if(! (p->next)||j>i-1)returnERROR//删除位置不合理 q=p->next;p->next=q->next//删除结点 e=q->data;free(q);//释放结点 returnOK; }//ListDelete_L (3)创建单链表 VoidCreateList_L1(LinkList&L,intn){ //按输入逆序建立n个元素的单链表 L->head=(Lnode*)malloc(sizeof(LNode)); L->head->next=NULL;//建立带头结点的空链 for(i=n;i>0;--i){ p=(Lnode*)malloc(sizeof(LNode));//生成新结点 scanf(&p->data);//输入元素值 p->next=L->head->next; L->head->next=p;//插入到表头 } }//CreateList_L1 VoidCreateList_L2(LinkList&L,intn){ //按输入顺序建立n个元素的单链表 L->head=(Lnode*)malloc(sizeof(LNode)); L->head->next=NULL;//建立带头结点的空链 for(i=0;i p=(Lnode*)malloc(sizeof(LNode));//生成新结点 scanf(&p->data);//输入元素值 p->next=NULL; if(L->head->next==NULL)L->head->next=p; elseq->next=p; q=p;//插入到表尾 } }//CreateList_L2 4、循环链表: 最后一个结点的指针域的指针又指回第一个结点的链表。 和单链表的差别仅在于: 判别链表中最后一个结点的条件不再是“后继是否为空”,而是“后继是否为头结点”。 5、双向链表的操作特点: 1、“查询”和单链表相同;2、“插入”和“删除”时需要同时修改两个方向上的指针 TypedefstructDuLnode{ ElemTypedata;//数据域 structDuLNode*prior;//指向前驱的指针 structDuLNode*next;//指向后继的指针 }DuLNode; TypedefstructDulList{ DulList*head; }DullinkList; 插入: 在双向链表中的p结点前插入一个s结点 {s->prior=p->prior;/*①*/ s->next=p;/*②*/ p->prior->next=s;/*③*/ p->prior=s;/*④*/ } 删除: 在双向链表中删除p结点 {p->prior->next=p->next;/*①*/ p->next->prior=p->prior;/*②*/ free(p);/*③*/ } 第三章 1、栈、队列的特点: ☐从数据元素间的逻辑关系看是线性表 ☐从操作方式与种类看不同于线性表: 栈与队列是操作受限的线性表 2、栈的基本概念栈---是限制仅在线性表的一端进行插入和删除运算的线性表。 栈顶(TOP)--允许插入和删除的一端。 栈底(bottom)--不允许插入和删除的一端。 空栈--表中没有元素。 栈--又称为后进先出的线性表 3、栈中元素的特性: 1、具有线性关系2、后进先出 4、栈的进栈出栈规则: a)按序进栈: 有n个元素1,2,…,n,它们按1,2,…,n的次序进栈(i进栈时,1~(i-1)应该已经进栈); b)栈顶出栈: 栈底最后出栈; c)时进时出: 元素未完全进栈时,即可出栈。 5、栈的表示与实现 顺序栈即栈的顺序存储结构: 一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。 /*栈的顺序存储结构描述*/ #defineSTACK_INIT_SIZE100/*存储空间的初始分配量*/ #defineSTACKINCREMENT10/*存储空间的分配增量*/ typedefstruct{ SElemType*base;/*存储空间基址*/ inttop;/*栈顶指针*/ intstacksize;/*当前分配的存储容量*/ }SqStack; 1、附设一个栈底指针base,总是指向栈底。 2、附设一个栈顶指针top。 空栈时,top=base;非空栈时,总是指向栈顶元素+1的位置。 ☐栈满s->top==s->stacksize ☐栈空s->top==0 ☐插入一个栈顶元素,指针top增1; ☐删除一个栈顶元素,指针top减1; ☐非空栈中的栈顶指针始终在栈顶元素的下一个位置上 3、进栈出栈 voidStackPush_sq(sqStack*s,inte){ int*newbase; if(s->top==s->stacksize) {newbase=(int*)realloc(s->base,(s->stacksize+STACKINCRMENT)*sizeof(int)); if(! newbase){printf("overflow! ");exit (1);} s->base=newbase; s->stacksize+=STACKINCRMENT; } s->base[s->top]=e; s->top++; } intStackPop_sq(sqStack*s){ if(s->top==0){ printf("thestackisempty! \n"); exit (1);} else{s->top--; return(s->base[s->top]);} } 链栈: 注意: 链栈中指针的方向指向前驱结点! 例: EXP=a×b+(c-d/e)×f v前缀: +×ab×-c/def v中缀: a×b+c-d/e×f v后缀: ab×cde/-f×+ 6、队列 ⏹队列: 只允许在表的一端进行插入,而在表的另一端进行删除的线性表。 ☐队尾(rear)——允许插入的一端 ☐队头(front)——允许删除的一端 ⏹队列特点: 先进先出(FIFO) 7、队列类型的实现 ⏹链队列——队列的链式表示和实现 ⏹顺序队列——队列的顺序表示和实现用一组连续的存储单元依次存放队列中的元素 8、顺序队列运算时的头、尾指针变化 设两个指针front,rear,约定: rear指示队尾元素;front指示队头元素前一位置初值front=rear=0 空队列条件: Q.front==Q.rear 队列满: Q.rear-Q.front=MAXQSIZE 入队列: Q.base[rear++]=x; 出队列: x=Q.base[++front]; 存在问题: 设数组维数为M,则: ⏹当rear-front=m时,再有元素入队发生溢出——真溢出 ⏹当rear已指向队尾,但队列前端仍有空位置时,再有元素入队发生溢出——假溢出! 队列的顺序存储结构 #defineMAXQSIZE100/*队列的最大长度*/ Typedefstruct{ QElemType*base;/*动态分配存储空间*/ intfront;/*头指针*/ intrear;/*尾指针*/ }SqQueue; /*将循环队列Sq初始化置为空循环队列*/ voidInitQueue(SqQueue*Sq) {Sq->base=(QElemType*)malloc(MAXQSIZE*sizeof(QElemtype)); if(! Sq->base)exit (1); Sq->front=Sq->rear=0; }/*InitQueue*/ /*在循环队列Sq的尾部入队一个新元素x*/ voidEnQueue(SqQueue*Sq,ElemTypex) {if((Sq->rear+1)%MAXQSIZE==Sq->front) exit (1);/*队列已满*/ Sq->base[Sq->rear]=x; Sq->rear=(Sq->rear+1)%MAXQSIZE; }/*EnQueue*/ /*循环队列Sq出队一个元素,并存人y中*/ intDelQueue(SqQueue*Sq) {if(Sq->front==Sq->rear) exit (1);/*队列已空*/ y=Sq->base[Sq->front]; Sq->front=(Sq->front+1)%MAXQSIZE; returny; }/*DelQueue*/ 9、循环队列: 将数组首尾相接(即: base[0]连在base[m-1]之后)。 入/出队列运算 利用“模运算”,则: Ø入队: Q.rear=(Q.rear+1)%MAXQSIZE Ø出队: Q.front=(Q.front+1)%MAXQSIZE 即一个大小为MAXQSIZE的循环队列最多有MAXQSIZE-1个元素 队满和队空判断条件: 队空: Q.rear=(Q.front) 队满: (Q.rear+1)%MAXQSIZE=Q.front 10、链队列 typedefstructQNode{ QElemTypedata; structQNode*next; }QNode; typedefstruct{ QNode*front;/*队头指针*/ QNode*rear;/*队尾指针*/ }LQueue; /*在链队列Lq的尾部插入一个新的元素x*/ voidEnQueue_L(LQueue*Lq,ElemTypex) {QNode*p; p=(QNone*)malloc(sizeof(QNone)); p->data=x; p->next=NULL; Lq->rear->next=p;Lq->rear=p; }/*EnQueue_L*/ /*删除队列Lq的队头元素,并存入y中*/ intDelQueue-L(LQueue*Lq){ if(Lq->front==Lq->rear) exit (1);/*队列已空*/ p=Lq->front->next;/*p指向队头结点*/ y=p->data; Lq->front->next=p->next; if(Lq->rear==p) Lq->rear=Lq->front;/*尾指针指向头结点*/ free(p); returny; }/*DelQueue-L*/ 第四章 一、1、串的基本概念 ⏹串---由零个或多个字符组成的有限序列,一般记为: s='a1a2...an'(n≥0) ⏹串中字符的个数n称为串的长度;零个字符,即长度为零的串称为空串,用或''表示。 空串不等于空格串,空格串: 由一个或多个空格组成的串 子串: 串中任意个连续的字符组成的子序列 主串: 包含子串的串相应地称为主串 相等: 两个串的长度相等,并且对应位置的字符都相同。 2、串结构与线性表结构的比较: 逻辑结构: 极为相似,区别仅在于串的数据对象约束为字符集。 基本操作: 有很大差别1、线性表大多以“单个元素”作为操作对象2、串通常以“串的整体”作为操作对象 3、串类型定义 4、串赋值StrAssign、串复制Strcopy、串比较StrCompare、求串长StrLength、串联接Concat以及求子串SubString等六种操作构成串类型的最小操作子集。 1、StrAssign(&T,chars)初始条件: chars是字符串常量。 操作结果: 把chars赋为T的值。 等价于C语言中的strset函数 2、StrCopy(&T,S)初始条件: 串S存在。 操作结果: 由串S复制得串T。 等价于C语言中的strcpy函数 3、StrCompare(S,T)初始条件: 串S和T存在。 操作结果: 若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0。 等价于C语言中的strcmp函数(按ASCII码值进行大小比较) 4、StrLength(S)初始条件: 串S存在。 操作结果: 返回S的元素个数,称为串的长度。 等价于C语言中的strlen函数 5、Concat(&T,S1,S2)初始条件: 串S1和S2存在。 操作结果: 用T返回由S1和S2联接而成的新串。 例如: Concate(T,man,kind)求得T=mankind等价于C语言中的strcat函数 6、SubString(&Sub,S,pos,len)初始条件: 串S存在,1≤pos≤StrLength(S)且0≤len≤StrLength(S)-pos+1。 操作结果: 用Sub返回串S的第pos个字符起长度为len的子串。 子串为“串”中的一个字符子序列。 例如: SubString(sub,'commander',4,3),求得sub='man'; SubString(sub,'commander',1,9),求得sub='commander'; SubString(sub,'commander',9,1),求得sub='r'; 起始位置pos和子串长度len之间存在约束关系,pos+len<=StrLength(S)+1 SubString('student',5,0)=? ——长度为0的子串为“合法”串 5、Index(S,T,pos)初始条件: 串S和T存在,T是非空串,1≤pos≤StrLength(S)。 操作结果: 若主串S中存在和串T值相同的子串,则返回它在主串S中第pos个字符之后第一次出现的位置;否则函数值为0。 “子串在主串中的位置”指子串中的第一个字符在主串中的位序。 假设S=abcaabcaaabc,T=bcaIndex(S,T,1)=2Index(S,T,3)=6Index(S,T,8)=0 6、Replace(&S,T,V)初始条件: 串S,T和V均已存在,且T是非空串。 操作结果: 用V替换主串S中出现的所有与(模式串)T相等的不重叠的子串。 例如: 假设S=abcaabcaaabca,T=bca若V=x,则经置换后得到S=abcaabcaaabca 7、StrInsert(&S,pos,T)初始条件: 串S和T存在,1≤pos≤StrLength(S)+1。 操作结果: 在串S的第pos个字符之前插入串T 例如: S='chater',T='rac',则执行StrInsert(S,4,T)之后得到S='character' 二、串的表示和实现 1、定长顺序存储表示: 用一组地址连续的存储单元存储串值的字符序列,称为顺序串。 可用一个数组来表示。 特点: ①串的实际长度可在这个预定义长度的范围内随意设定,超过预定义长度的串值则被舍去,称之为“截断”。 ②按这种串的表示方法实现的串运算时,其基本操作为“字符序列的复制” 顺序存储结构中,串操作的基本操作为“字符序列的复制”,其时间复杂度基于复制的字符序列的长度。 定长顺序串结构类型 #defineMAXSTRLEN150 typedefstruct{ charc[MAXSTRLEN]; intlen; }SString; 2、堆分配存储表示: 特点: 仍以一组地址连续的存储单元存放串值字符序列,但它们的存储空间是在程序执行过程中动态分配而得的。 串操作实现的算法为: 先为新生成的串分配一个存储空间,然后进行串值的复制。 3、串的模式匹配算法 intIndex(SStringS,SStringT,intpos){//从主串s的下标pos起,串t第一次出现的位置,成功返回位置序号,不成功返回0 i=pos;j=1;//主串从pos开始,模式串从1开始 while(i<=S.len&&j<=T.len) { if(S.c[i]==T.c[i]){++i;++j;}//相等时,同时推进 else{i=i-j+2;j=1;} } if(j>T.len)returni-T.len;//匹配成功时,返回起始位置 elsereturn0; }//Index 4、计算模式串的next函数值和修正的next函数值 第六章 一、树的定义 1、树型结构: (非线性结构)至少存在一个数据元素有两个或两个以上的直接前驱(或直接后继)元素的数据结构。 树的定义: 是n(n≥0)个结点的有限集合T,对于任意一棵非空树,它满足: 有且仅有一个特定的称为根(root)的结点;当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,….,Tm,其中每个集合本身又是一棵树,称为根的子树。 上述树的定义是一个递归定义。 2、基本术语 结点: 包含一个数据元素及若干指向其子树的分支。 结点的度: 结点拥有的子树数。 叶子(或终端)结点: 度为零的结点。 分支(或非终端)结点: 度大于
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 整理 期末 复习