数据结构复习.docx

上传人:b****8 文档编号:10202614 上传时间:2023-02-09 格式:DOCX 页数:49 大小:1.45MB
下载 相关 举报
数据结构复习.docx_第1页
第1页 / 共49页
数据结构复习.docx_第2页
第2页 / 共49页
数据结构复习.docx_第3页
第3页 / 共49页
数据结构复习.docx_第4页
第4页 / 共49页
数据结构复习.docx_第5页
第5页 / 共49页
点击查看更多>>
下载资源
资源描述

数据结构复习.docx

《数据结构复习.docx》由会员分享,可在线阅读,更多相关《数据结构复习.docx(49页珍藏版)》请在冰豆网上搜索。

数据结构复习.docx

数据结构复习

第二章

1.线性表的结构特点:

在数据元素的非空有限集中,

1)存在唯一的一个被称为“第一个”的数据元素。

2)存在唯一的一个被称为“最后一个”的数据元素。

3)除第一个数据元素之外,集合中的每个数据元素均只有一个直接前驱。

4)除最后一个数据元素之外,集合中每个数据元素均只有一个直接后继。

2.顺序表的存储结构和基本操作:

见本

3.顺序表的优点和缺点:

优点:

(1)构造原理简单、直观,易理解。

(2)元素的存储地址可以通过一个简单的解析式计算

出来。

LOC(ai)=LOC(a1)+(i-1)×k。

缺点:

(1)存储空间分配需要事先确定。

(2)需要一片地址连续的存储空间。

(3)基本操作(如插入、删除)的时间效率较低,为什么?

4.单链表的存储结构及基本操作:

见本。

5.单链表的优点和缺点:

优点:

1.插入、删除操作方便。

2.不需预先分配空间。

3.它是一种动态结构,整个存储空间为多个链表共用。

缺点:

1.指针占用额外空间。

2.不能随机存取,查找速度慢。

第三章

1.栈的特点:

先进后出/后进先出。

2.栈的存储结构定义:

见本

3.栈的基本操作的功能及调用格式:

InitStack(&S):

构造一个空栈S

DestroyStack(&S):

销毁已存在的栈S

ClearStack(&S):

将已存在的栈S清空

StackEmpty(S):

判断S是否为空栈(若为空,返回TRUE,否则,返回FALSE)

StackLength(S):

计算栈S的长度(返回栈S的元素个数)

GetTop(S,&e):

用e返回栈S的栈顶元素的值

Push(&S,e):

元素e入栈,作为新栈顶元素

Pop(&S,&e):

栈顶元素出栈,用e返回元素值

StackTraverse(S,visit()):

对S中的每个数据元素按从栈顶到栈底的顺序调用函数visit()。

(StatusVisit(e)

{

if(e==NULL)returnERROR;

elsecout<

returnOK;

}

4.中缀表达式转前缀表示式和后缀表达式:

(2分)

前缀表达式:

操作符在操作数的前面(从右往左看,从右往左写)

后缀表达式:

操作符在操作数的后面(从左往右看,从左往右写)

中缀表达式转换为后缀表达式的规则

1)建立运算符栈

2)设表达式的结束符和运算符栈的栈底为‘#’

3)从左向右读表达式

(1)若读取的是操作数,直接输出到后缀表达式;

(2)若读取的是‘(’,直接进栈

(3)若读取的是‘)’,连续输出栈顶运算符到后缀表达式,直到弹出‘(’为止;

(4)若读取的是非括号运算符,将之与栈顶运算符进行比较:

若比栈顶运算符的优先数高,则直接进栈;否则将栈顶运算符发送到到后缀表达式,再继续比较,直到栈为空或栈顶元素的优先级低于当前读取的运算符的优先级。

4)若表达式未读取完,重复3;若表达式读取完,而栈非空,则依次将栈中运算符发送给后缀表达式,直到栈空。

5.队列的特点:

先进先出的线性表。

只允许在表的一端进行插入,在另一端删除元素。

允许插入的一端称为队尾(rear),允许删除的一端称为队首(front)。

6.链队列的存储结构:

见本

*7.循环队列(环状的顺序队列)(6分):

特点:

用一组地址连续的存储单元依次存储从队首到队尾的元素,

front和rear分别指示队头元素和队尾元素的位置。

约定:

1.初始化,空队列front=rear=0。

2.插入新队尾元素时“尾指针rear增1”,删除队头元素时“头指针front增1”。

3.非空队列front始终指向队头元素,rear始终指向队尾元素的下一个位置(空位置)。

每出一次:

Q.front=Q.front+1;每入一次:

Q.rear=Q.rear+1;

Q.front=(Q.front+1)%InitSize;

Q.rear=(Q.rear+1)%InitSize;

判断队列空间的“空”与“满”:

(1)少用一个元素空间的循环队列Q的空满判断条件(常用判断方法)

为空:

Q.front=Q.rear

为满:

(Q.rear+1)%MAXSIZE=Q.front

(2)以标志位来区分循环队列Q为满判断条件:

(加临时长度)

为空:

Q.front=Q.rear,且length=0

为满:

Q.front=Q.rear,且length=MAXSIZE

队列的基本操作的功能和调用格式:

InitQueue(&Q):

构造一个空队列Q

DestroyQueue(&Q):

销毁已存在的队列Q

ClearQueue(&Q):

将已存在的队列Q清空

QueueEmpty(Q):

判断Q是否为空队列

QueueLength(Q):

计算队列Q的长度

GetHead(Q,&e):

用e返回Q的队头元素的值

EnQueue(&Q,e):

插入元素e作为新队尾元素(入队列)

DeQueue(&Q,&e):

删除Q的队头元素,用e返回元素值(出队列)

QueueTraverse(Q,visit()):

对Q中的每个数据元素按从队头到队尾的顺序调用函数visit()

第四章

1.串的基本操作的功能:

StrCopy(&T,S):

由串S复制得到串T

StrEmpty(S):

判断S是否为空

StrLength(S):

返回串S的长度

ClearString(&S):

将串S清空

Concat(&T,S1,S2):

连接串S1和S2,生成新串T

SubString(&Sub,S,pos,len):

返回串S中第pos个字符起长度为len的子串

Index(S,T,pos):

返回主串S中第pos个字符之后子串T第一次出现的位置

2.串的模式匹配next[j]的求法:

见本。

3.改进的串的模式匹配的基本思想:

匹配过程中出现比较不等(即si<>pj)时,不需回溯i指针,而是利用已

经得到的“部分匹配”的结果,立即确定模式右移的位数和继续比较

的字符,即主串中第i个字符应与模式中第k个字符比较。

程序见本。

4.练习:

1.空串与空格串有何区别,字符串中的空格符有何意义?

空串在串处理中有何作用?

2.设s=’IAMASTUDENT’,t=’GOOD’,q=‘WORKER’。

求:

StrLength(s);StrLength(t)

SubString(s,8,7);SubString(t,2,1)

Index(s,’A’),Index(s,t)

Replace(s,’STUDENT’,q)

Concat(SubString(s,6,2),Concat(t,SubString(s,7,8)))。

答案:

1.不含任何字符的串称为空串,其长度为0。

 仅含有空格字符的串称为空格串,其长度为串中空格字符的个数。

空格符可用来分隔一般的字符,便于人们的识别和阅读,但计算串长时应包括这些空格符。

 空串在串处理中可作为任意串的子串;

2.StrLength(s)=14,StrLength(t)=4,

SubString(s,8,7)=’STUDENT’,

SubString(t,2,1)=’O’,Index(s,’A’)=3,

Index(s,t)=0,

Replace(s,’STUDENT’,q)=’IAMAWORKER’,

Concat(SubString(s,6,2),Concat(t,SubString(s,7,8)))=’AGOODSTUDENT’

5.课后题:

(1)求出:

‘T=abcaabbabcabaacbacba’的next函数值。

j1234567891011121314151617181920

模式串abcaabbabcabaacbacba

next[j]01112231234532211211

(2)试写一在串的堆存储结构上实现串的替换操作

Replace(&S,T,V)的算法(可以直接调用串的基本操作)

voidReplace(HString&S,HStringT,HStringV)

{

k=index(S,T,1);

if(k)

{

StrAssign(temp,””);

n=StrLength(T);m=StrLength(S);

while(k){

StrAssign(temp,Concat(temp,SubString(S,1,k-1),V));

m-=(k-1)-n;

StrAssign(S,SubString(S,k+n,m));//S为每次替换后的剩余串

k=index(S,T,1);

}//while

StrAssign(S,Concat(temp,S));

}//endif

}

第五章

1.多维数组元素物理地址的求法:

对b1×b2×…×bnn维数组:

LOC(i1,i2,…,in)=LOC(0,0,…,0)+(b2×b3×…×bn×i1+b3×b4×…×bn×i2+…+bn×in-1+in)×L

N维数组的数据元素存储位置的计算公式:

LOC(j1,j2,…,jn)=LOC(0,0,…,0)+(b2…bnj1+b3…bnj2+…+bnjn-1+jn)L

=LOC(0,0,…,0)+

(1)

其中,cn=L,ci-1=bi*ci,1

(1)称为n维数组的

映象函数。

2.广义表;

(1)广义表(GeneralizedLists):

n(n>=0)个数据元素的有序序列,一般记为:

LS=(α1,α2,…,αn)

LS为广义表的名称,n是它的长度。

αi可以是单个元素或广义表,分别称为广义表LS的原子和子表。

广义表LS非空时,第一个元素α1为LS的表头(Head);其余元素组成的表(α2,α3,…,αn)是LS的表尾(Tail)(注:

表尾一定是个广义表)。

深度:

广义表所含括号的重数。

空表的深度为1,原子的深度为0。

广义表L的深度为L中各个子表深度的最大值加1。

长度:

广义表中数据元素的个数,空表的长度为0.

(2)求表头函数:

GetHead(L)

求表尾函数:

GetTail(L)

求表长函数:

GetLength(L)

3.课后作业:

1.假设按低下标优先存储整数数组A9×3×5×8时,第一个元素的字节地址是100,每个整数占四个字节。

问下列元素的存储地址是什么?

1)a0000    2)a1111    3)a3125    4)a8427

见本

第六章

1.孩子兄弟表示法:

以二叉链表作树的存储结构,结点的两个域分别指向该结点的第一

个孩子结点和下一个兄弟结点。

存储结构:

typedefstructCSNode {

TElemTypedata;

structCSNode*firstchild,*nextsibling;

}CSNode,*CSTree;

2.树与二叉树的转换方法:

(1)将树转换为二叉树:

关键是把n个分支变为两个分支,步骤如下:

1)保留所有结点与其第一个子结点的链接

2)打断所有结点原本与其他子结点(不是第一个孩子结点的结点)的链接,并连结所有兄弟结点(拥有同一个父节点的子结点)

3)将兄弟结点顺时钟转45度。

(2)将二叉树转换为树

1)二叉树的根即为树的根;

2)二叉树的左子树为树的左子树,从根开始一直向右,遇到的右子树则将其作为树的子树。

3)打断所有结点与其右结点的链接。

详细例题见本

3.森林与二叉树之间的转换方法:

对于任意一棵二叉树B=(LBT,Node(root),RBT)可按如下规则转换得

到由n棵子树构成的森林F={T1,T2,…,Tn},其中第一棵树T1由根结点

ROOT(T1)和子树森林{t11,t12,…,t1m}构成:

若二叉树B为空树,则与其对应的森林F为空集;否则,由二叉树的根

结点(root)复制得到森林中第一棵树的根结点ROOT(T1),由二叉树

中的左子树LBT转换构造森林中第一棵树的子树森林{t11,t12,…,t1m},由二叉

树中的右子树RBT转换构造森林中其余树构成的森林{T2,T3,…,Tn}。

步骤如下:

(1)二叉树的根即为森林中第一棵树的根;

(2)从二叉树的根开始向右,遇到右子树,剪断其连接,使根及其左子树,成

为第一棵树;如此往复处理其右子树。

(3)将每棵二叉树转换为树。

转换过程见本;

4.树的两种遍历方法:

(1)先根遍历:

先遍历树的根结点,然后依次先根遍历根的每棵树。

(对应二叉树的先序遍历)

(2)后根遍历:

先依次后根遍历每棵子树,然后访问根结点。

(对应二叉树的中序遍历)书P139

5.森林的两种遍历方法:

(1)先序遍历

 若森林非空,则先访问森林中第一棵树的根结点,再先序遍历第

一棵树中根结点的子树森林,然后先序遍历除去第一棵树之后剩

余的树构成的森林。

(2)中序遍历

  若森林非空,则先中序遍历第一棵树根结点的子树森林,再访问

第一棵树的根结点,然后中序遍历除去第一棵树之后剩余的树构成的森林

6.树、森林的每种遍历方法与二叉树三种遍历方法之间的对应关系

1)树和森林进行的各种操作均可通过对“二叉树”相应的操作来完成,但要注意:

此时的二叉树其左、右子树和根结点之间的关系不再是“左、右孩子”,而左子树是根的“孩子”,右子树是根的“兄弟们”。

2)当森林转化成二叉树时,其第一棵树的子树森林转化成左子树,剩余树的森林转换成右子树,则森林的先序和中序遍历即为其对应的二叉树的先序(前序)和中序遍历。

3)当树以二叉链表形式存储时,树的先根遍历和后根遍历可借用二叉树的先序(前序)和中序遍历的算法实现。

7.二叉树的五个特性:

二叉树有五种基本形态:

(1)空二叉树

(2)只有根结点的二叉树

(3)左子树为空的二叉树

(4)右子树为空的二叉树

(5)左、右子树都不为空的二叉树

8.两种特殊形态的二叉树:

(1)满二叉树

深度为k且有2k-1个结点的二叉树。

第一层20

第二层21

第三层22

满二叉树第i层有2i-1个结点;

(2)完全二叉树

 定义:

深度为k,有n个结点的二叉树当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称为完全二叉树。

特点:

1)叶子结点只可能出现在层次最大的两层上,并且最下面一层的结点都集中在该层最左边的连续的若干位置上。

2)对任一结点,若其右分支下子孙的最大层次为i,则其左分支下子孙的最大层次必为i或i+1。

9.在完全二叉树上求叶子节点数的方法:

在二叉树上,分支总数B=2*n2+n1(n1,n2分别为度为1、2的结点个数)

结点总数:

n=B+1;n=2*n2+n1+1

因为n=n0+n1+n2,故n2=n0-1;所以n=2*n0+n1-1

(在完全二叉树上,度为1的结点的个数只可能为0或1。

当结点总数n

为奇数时,n1=0;当结点总数为偶数时,n1=1。

10.二叉树的两种存储结构:

(1)顺序存储:

1)完全二叉树的顺序存储:

用一组地址连续的存储单元依次自上而

下、自左至右存储完全二叉树上的结点元素。

即将完全二叉树上编号为i的结点元素存储在一维数组中下标为i的分量中。

2)一般二叉树的顺序存储

将其每个结点与完全二叉树上的结点编号相对照,存储在一维数组相应的分量中,根结点存储在1号单元。

若父节点编号为n,可以得到:

(1)左子节点的编号为父节点编号乘以2:

2*n

(2)右子节点编号为父节点编号乘以2加1:

2*n+1

(2)链式存储结构:

1.二叉链表 

链结点的构造为

左指针域 数据域 右指针域

二叉链表的存储结构

typedef struct BiTNode {

 TElemType data;

struct BiTNode *lchild,*rchild;

}BiTNode,*BiTree;

11.二叉树的三种遍历方法的思想:

前序(先根)遍历:

(1)访问根结点

(2)前序遍历左子树

   (3)前序遍历右子树

中序遍历二叉树:

(1)中序遍历左子树

(2)访问根结点

(3)中序遍历右子树

后序(根)遍历:

(1)后序遍历左子树

(2)后序遍历右子树

        (3)访问根结点

能够根据二叉树的遍历序列画出二叉树。

12.赫夫曼树(2分):

特点:

N个叶子结点的赫夫曼树供有2N-1个结点、权值最大的结点的层次值最小,且没有度为1的结点。

构造:

(1)根据给定的n个权值{w1,w2,…,wn}构成n棵二叉树的集合F={T1,T2,…,Tn},其中每棵二叉树Ti中只有一个带权为wi的根结点,其左右子树均空。

(2)在F中选取两棵结点的权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和。

(3)在F中删除这两棵树,同时将新得的二叉树加入F中。

(4)重复

(2)、(3),直至F只含一棵树为止。

  这棵树便是赫夫曼树。

练习:

1.若二叉树用二叉链表作存贮结构,则在n个结点的二叉树链表中只有n-1个非空指针域。

2.一棵深度为6的满二叉树有31个分支结点和32个叶子。

(分支结点为度不为0的结点)

3.一棵含有n个结点的k叉树,可能达到的最大深度为n,最小深度为完全k叉树,。

4.设一棵完全二叉树具有1000个结点,则此完全二叉树有500个叶子结点,有499个度为2的结点,

有1个结点只有非空左子树,有0个结点只有非空右子树。

5.深度为的k完全二叉树至少有2k-1个结点;对于深度为k的满二叉树,如果从上到下、从左到右给结点编号(从1开始),则最大的叶子结点编号是2k-1。

作业

第七章

1.邻接矩阵

1)邻接矩阵的定义

 设图G=(V,E),n(n≥1)是图的顶点个数,则G的邻接矩阵为一个n阶方阵arcs[n][n]。

arcs[i][j]=0(vi,vj)或<vi,vj>不存在

1(vi,vj)或<vi,vj>存在

当G为网时,

arcs[i][j]=weight(vi,vj)或<vi,vj>存在,

其权值为weight

∞(vi,vj)或<vi,vj>不存在

2)邻接矩阵的性质(*)

(1)当图中各顶点的序号确定后,图的邻接矩阵是唯一确定的。

(2)无向图和无向网的邻接矩阵是一个对称矩阵。

(3)无向图邻接矩阵中第i行(或第i列)非0元素的个数即为第i个顶点的度。

(4)有向图邻接矩阵中第i行非0元素个数为第i个顶点的出度,第i列非0元素个数为第i个顶点的入度,第i个顶点的度为第i行与第i列非0元素个数之和。

(5)无向图邻接矩阵中非0元素个数是边数的两倍,有向图邻接矩阵中非0元素个数与弧数相等。

3)邻接矩阵法的实现

 邻接矩阵存储结构用两个数组来实现。

(1)一维数组

  来存储数据元素的(顶点)的信息。

顶点可按任意顺序存放,通常把存放顶点元素的数组下标作为该顶点的编号。

(2)二维数组(即邻接矩阵)

  用来存储数据元素之间的关系(边或弧)的信息。

有N个顶点的图,其邻接矩阵是N阶方阵,记为arcs[N][N]。

4)图的邻接矩阵存储表示(*)

typedefenum{DG,DN,UDG,UDN}GraphKind;//图的四种类型

typedefstructArcCell{

 VRTypeadj;       //顶点关系类型

 infoType*info;      //与该边(或弧)相关的信息

}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedefstruct{

 VertexTypevexs[MAX_VERTEX_NUM];//顶点向量

 AdjMatrixarcs;         //邻接矩阵

 intvexnum,arcnum;    //图的当前顶点数和弧数

 GraphKind kind;       //图的种类标志

}Mgraph;

5)图的基本操作的实现

2.邻接表

1)定义:

邻接表(AdjacencyList):

为图中每个顶点建立一个反映邻接关系的单链表,把该顶点的所有邻接顶点的序号及与边或弧相关的信息链接起来,第i个单链表中的结点表示依附于顶点vi的各条边(或弧)。

2)邻接表的表头结点包括两个域:

(1)顶点的名称或其它有关信息(data域)

(2)指向链表中第一个结点(firstarc域)

表头结点可以顺序存储,也可链式存储。

邻接表的表结点包括三个域:

(1)邻接点在图中的位置(adjvex域)

(2)指向下一个弧或边的指针(nextarc域)

(3)与弧或边相关的信息(info域)

adjvex

nextarc

info

2)图的邻接表存储表示

typedefstructArcNode{ 

 intadjvex;   //该弧(或边)指向的顶点的位置 

 structArcNode*nextarc;  //指向下一条弧(或边)的指针 

 infoType*info;      //该弧(或边)的相关信息

}ArcNode;    

typedefstructVnode{  

 VertexTypedata; //顶点信息

 ArcNode*firstarc;//指向第一条依附该顶点的弧(或边)的指针

}VNode,AdjList[MAX_VERTEX_NUM];

typedefstruct{

 AdjListvertices;

 intvexnum,arcnum;

 intkind;    //图的种类标志

}ALGraph;    //邻接表

3)图的基本操作的实现

3.图顶点入度、出度、度的计算方法

在有向图中:

顶点v的入度(InDegree):

以顶点v为弧头的弧的数目,记为ID(v)。

顶点v的出度(OutDegree):

以顶点v为弧尾的弧的数目,记为OD(v)。

顶点v的度(Degree):

与顶点相关联的弧的数目,记为TD(v)。

TD(v)=ID(v)+OD(v)

具有n个顶点的有向图最多有n(n-1)条边。

在无向图中:

顶点v的度(Degree):

与顶点v相关联的边的数目,记为TD(v)。

有n个顶点,e条边的图,满足关系 e=

具有n个顶点的无向图最多有n(n-1)/2条边.

4.连通图

1)在无向图G中,若从顶点vi到顶点vj存在路径,则称vi和vj是连通的。

连通图(ConnectedGraph):

图中任意两顶点都是连通的。

连通分量(ConnectedComponent):

无向图中的极大连通子图。

图见本

2)在有向图G中,若从顶点vi到顶点vj有路径,则称vi和vj

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

当前位置:首页 > 高等教育 > 文学

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

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