1.(2分)单向链表中指针p所指结点有后继结点的条件是 p->next != NULL;。
2.(2分)设二维数组A[9][10]从首地址SA开始按行优先顺序存放,每个元素占用3个存储单元,则元素a[8][5]的起始地址为 SA+255 。
3.(3分)下面算法的时间复杂性为 O(n2)、O(1) ,空间复杂性为 。
void bubble_sort(int a[], int n) {
for (i=n-1, change=true; i>1 && change; --i){
change=false;
for (j=0; j<i; ++j)
if (a[j]>a[j+1])
{ t=a[j]; a[j]=a[j+1]; a[j+1]=t; change=true}
}
}
4.(3分)在采用顺序存储结构有n个元素的线性表中:插入或删除一个元素,需要平均移动
n/2 和(n-1)/2 个元素;逻辑上相邻的元素的物理位置 一定 紧邻。单向链表中逻辑上相邻的元素的物理位置 不一定 紧邻。
5.(2分)对N个元素的序列进行起泡排序时,最少的比较次数是 。
6.(3分)对二叉树进行线索化是利用结点中left或right为NULL的域,使left指向 ,right指向 ;进行线索化的主要目的是 该节点的直接前驱 该节点的直接后继 方便查找结点的直接前驱和直接后继
1.若某线性表中常用操作是在一个结点i之前插入或删除一个结点,则采用( D )存储方式最节省运算时间。
A、单向链表 B、仅有头指针的单循环链表 C、仅有尾指针的单循环链表 D、双向链表
2.已知完全二叉树有80个结点,则整棵二叉树有( B )个度为1的结点。
A、0 B、1 C、2 D、17
3.在某单向链表L中,指针p指向结点a,要删除结点a的后继结点b,则指针修改语句为( )。
①p->next=p ② p->next=p->next->next ③ p=p->next->next ④p=p->next
4.已知L是带表头附加结点的非空单链表,且P结点既不是首元结点,也不是尾元结点,试从下列提供的答案中选择合适的语句序列。
① 删除P结点直接后继结点的语句序列是 KCN 。
② 删除P结点直接前驱结点的语句序列是 JLHKCN 。
③ 删除P结点的语句序列是 JLGCN 。
A、 p=p->next B、p->next=p C、p->next=p->next->next
D、p=p->next->next E、while (p!=NULL) p=p->next
F、while (Q->next!=NULL) {P=Q; Q=Q->next}
G、while (p->next!=Q) p=p->next
H、while (p->next->next!=Q) p=p->next
I、while (p->next->next!=NULL) p=p->next J、Q=P K、Q=p->next
L、P=L M、L=L->next N、 (free(Q)
5.已知P结点是某双向链表的中间结点,试从下列提供的答案中选择合适的语句序列。
① 在P结点后插入S结点的语句序列是 LGCF 。
② 删除P结点的直接前驱结点的语句序列是 PBJR 。
③ 删除P结点的语句序列是 INQ 。
A、p->right=p->right->right B、p->left=p-> left -> left
C、p->right=s D、p->left=s E、s->right=p
F、s->left=p G、s->right=p->right H、s->left=p-> left
I、p->left->right=p-> right J、p->left->right=p
K、p->right->left =p L、p->right->left =s
M、p-> left->right=s N、p->right->left = p ->left
O、Q=P->right P、Q=P->left
Q、free§ R、free(Q) S、p->left->left->right=Q
6、在数据结构中,从逻辑上可以把数据结构分成(C )
A、动态结构和静态结构 B、紧凑结构和非紧凑结构
C、线性结构和非线性结构 D、内部结构和外部结构
7、任何一棵二叉数的叶子结点在先序、中序和后序遍历序列中的相对次序(A )
A、不发生改变 B、发生改变 C、不能确定 D、以上都不对
8、给定一组权值{1,2,3,4,5,6},构造一棵Hffman树,则树的带权路径长度WPL为( C )。
A、21 B、42 C、51 D、54
9、一棵二叉树的先序遍历序列是ABCDEFG,中序遍历序列是CBEFDGA,则该二叉树的后序遍历序列是( )。
①CFEGDBA ②GFEDCBA ③ACBEFGD ④CBDEFGA
10、下列关于图的叙述中,( B )是不正确的。
A、n个顶点的完全图具有n(n-1)/2条边。
B、图的广度优先搜索遍历类似于树的先根遍历。
C、一个连通图的生成树不一定是唯一的。
D、邻接表可以作为无向图和有向图的存储结构。
1.(6分)简述如下算法功能
status A(linkedList L) { //L是无表头附加结点的单链表
if (L && L->next){
Q=L; L=L->next; P=L;
While (P->next) P=P->next;
P->next=Q; Q->next=NULL;
}
return OK;
}
2.(12分)
1)写出二叉树BT的顺序存储结构、链式存储结构(二叉链表)的数据类型定义,并写出图3-1所示二叉树用这两种存储形式的存储图。
2)写出图3-2所示树对应的二叉树;并写出该树的先序遍历次序。
3.算法改错(4分)
下面是实现循环队列的算法,存在两处严重错误,请改正。
#define MAXQSIZE 100
typedef struct {
QelemType *queue;
int front, rear;
} Queue
status InitQueue(Queue &Q){ //构造一个空队列
Q.queue=(QelemType *)malloc(MAXQSIZE*sizeof(QelemType));
If (!Q.queue) exit(OVERFLOW);
Q.front=Q.rear=0;
Return OK;
}
status EnQueue(Queue &Q, QelemType e){
//插入元素e为Q的新的队尾元素
if (Q.rear % MAXSIZE==Q.front) return ERROR; //队列满
Q.queue[Q.rear]=e;
Q.rear=(Q.rear+1) % MAXQSIZE;
Return OK;
}
status DeQueue(Queue &Q,QelemType &e){
//若队列不空,则删除Q的队首元素,用e返回其值,并返回OK;否则返回ERROR
if ((Q.front+1)==Q.rear) return ERROR;
e=Q.queue[Q.front];
Q.front=(Q.front+1) % MAXQSIZE;
Return OK;
}
4.(9分)设计算法,删除采用顺序存储结构的线性表中的重复元素。
5.(9分)
1)请写出存储有向图的邻接矩阵、邻接表和逆邻接表的数据类型定义。
2)对于下图所示的有向图,请写出该图对应的邻接矩阵、邻接表和逆邻接表。
6.已知一组关键字为(19,14,23,1,68,20,84,27,55,11,10,79),试写出按哈希函数H(key) = key MOD 13和链地址法处理冲突所得的哈希表。(6分)
7.(6分)已知关键字序列为(45,24,53,40,12,25,90)。
(1) 试画出其对应的二叉排序树。
(2) 给出在二叉排序树中,查找元素12的查找过程。
8.对于关键字序列(49,38,65,97,76,13,27,49),写出利用快速排序第一趟排序的执行过程。(5分)
一、 填空(共15分)
1、p->next != NULL;
2、SA + 255
3、O(n2)、O(1)
4、n/2 和(n-1)/2 一定 不一定
5、N-1
6、该节点的直接前驱 该节点的直接后继 方便查找结点的直接前驱和直接后继
二、 单项选择题(共28分,每个2分)
1、D 2、B 3、②
4、① KCN ②JLHKCN ③JLGCN
5、① LGCF ②PBJR ③INQ
6、C
7、A
8、C
9、①
10、B
三、 应用题
Typedef struct BiNode{
TelemType data;
Struct BiTNode *l, *r;
}BiTNode, *BiTree;
图(3-1)按顺序存储:
2)先序遍历序列为 1234576。
3、算法改错(4分)
status EnQueue(Queue &Q, QelemType e){
//插入元素e为Q的新的队尾元素
if (Q.rear % MAXSIZE==Q.front) return ERROR; //队列满
改为:if ((Q.rear+1) % MAXSIZE==Q.front) return ERROR;
Q.queue[Q.rear]=e;
Q.rear=(Q.rear+1) % MAXQSIZE;
Return OK;
}
status DeQueue(Queue &Q,QelemType &e){
//若队列不空,则删除Q的队首元素,用e返回其值,并返回OK;否则返回ERROR
if ((Q.front+1)==Q.rear) return ERROR;
改为:if (Q.front==Q.rear) return ERROR;
e=Q.queue[Q.front];
Q.front=(Q.front+1) % MAXQSIZE;
Return OK;
}
4、
void delList(SqList *L)
{
for (int i=0; i<L->length; ++i)
{
for (int j=i+1; j<L->length; ++j)
{
if (L->elem[i] == L->elem[j])
{
if (j != L->length-1) //当前j不是最后一个元素
{
//与最后一个元素交换
ElemType tmp = L->elem[j];
L->elem[j] = L->elem[L->length-1];
L->elem[L->length-1] = tmp;
}
L->length--; //删除掉最后一个元素
} //end of if
} //end of for
} //end of for
}
5、(9分)
邻接矩阵数据类型定义:
#define VEX_NUM 20
typedef struct ArcCell{
VRType adj;
InfoType *info;
}ArcCell, AdjMatrix[VEX_NUM] [VEX_NUM];
typedef struct{
VertexType vex[VEX_NUM];
AdjMatrix arcs;
Int vexnum, arcnum;
}MGraph;
邻接表与数据类型定义:
#define VEX_NUM 20
typedef struct ArcNode{
int adjvex;
struct ArcNode *nextarc;
InfoType *info;
}ArcNode;
typedef struct VNode{
VertexType data;
ArcNode *firstarc;
}Vnode, AdjList[VEX_NUM];
typedef struct {
AdjList vertices;
Int vexnum, arcnum;
}ALGraph;
查找 12 的过程:45 –> 24 -> 12
8、(5分)已第一趟排序过程如下:
即第一趟排序的结果为:38 49 65 76 13 27 49 97。
1.若一个栈的输入序列是1、2、3、… …、n,输出序列的第一个元素是n,则第i个输出元素是 。
2.下面算法的时间复杂度为 ,空间复杂度为 ;
其功能为 。
void BFST (ALGraph G, Status (*Visit)(int v)) {//以邻接表存储图G
SqQueue Q; //顺序队列Q
QElemType u;
for(int v=0; v < G.vexnum; ++v) visited[v]=FALSE;
InitQueue(Q); //初始化Q ,置空辅助队列
for(v=0; v<G.vexnum; ++v)
if(!visited[v]) {
visited[v]=TRUE;
EnQueue(Q, v);
Visit(v);
while(QueueEmpty(Q)) {
DeQueue(Q, u); //队首元素出队,并置为u
for(w = FirstAdjVex(G, u); w; w = NextAdjVex(G, u, w))
if(! visited[w]) {
visited[w]=TRUE;
Visit(w);
EnQueue(Q, w);
} //if
} //while
} //if
} //BFST
3.在采用顺序存储结构有n个元素的线性表中:插入一个元素,需要平均移动
个元素;逻辑上相邻的元素的物理位置 紧邻。单向链表中逻辑上相邻的元素的物理位置 紧邻。
4.在单向链表中设置头附加结点的作用 。
5.一般树可转化为二叉树进行处理,但也可对树直接进行处理,这时其存储方式可以
为 、 。
6.对序列(49,38,65,97,76,27,13,50)采用快速排序法进行排序,以序列的第一个元素为基准元素得到的划分结果是___________ _______。
1.在有n个叶子结点的哈夫曼树中,其总结点的个数是 。
A.不确定 B.2n+1 C.2n D.2*n-1
2.已知P结点是某双向链表的中间结点,试从下列提供的答案中选择合适的语句序列。
① 在P结点后插入S结点的语句序列是 。
② 在P结点前插入S结点的语句序列是 。
③ 删除P结点的直接前驱结点的语句序列是 。
④ 删除P结点的语句序列是 。
A.p->right=p->right->right B.p->left=p-> left -> left
C.p->right=s D.p->left=s E.s->right=p
F.s->left=p G.s->right=p->right H.s->left=p-> left
I.p->left->right=p-> right J.p->left->right=p
K.p->right->left =p L.p->right->left =s
M.p-> left->right=s N.p->right->left = p ->left
O.Q=P->right P.Q=P->left
Q.delete P R.delete Q
3.一棵二叉树的先序遍历序列是ABCDEFG,中序遍历序列是CBEFDGA,则该二叉树的后序遍历序列是 。
A.CFEGDBA B.GFEDCBA C.ACBEFGD D.CBDEFGA
4.含n个关键字的二叉排序树的平均查找长度主要取决于 。
A.关键字的个数 B.树的形态 C.关键字的取值范围 D.关键字的数据类型
5.堆的形状是一棵_______。
A.二叉排序树 B.满二叉树
C.完全二叉树 D.平衡二叉树
6.将一棵有100个结点的完全二叉树从上到下,从左到右依次对结点进行编号,根结点的编号为1,则编号为49的结点的左孩子的编号为__ 。
A.98 B.99 C.50 D.48
7.设有字符序列{Q、H、C、Y、P、A、M、S、R、D、F、X},一趟排序的结果为{F、H、C、D、P、A、M、Q、R、S、Y、X},则是下列哪个排序算法。 __
A.起泡排序 B.初始步长为4的shell的排序
C.二路归并排序 D.以第一个元素为分界元素的快速排序
8. 树型结构最适合用来描述 。
A.有序的数据元素 B.无序的数据元素
C.数据元素之间的具有层次关系的数据 D.数据元素之间没有关系的数据
9.若频繁地对线性表进行插入和删除操作,该线性表应该采用_ ___存储结构。
A.散列 B.顺序 C.链式 D.索引
10.顺序查找法适合于存储结构为 的线性表。
A.散列存储 B.顺序存储或链接存储 C.压缩存储 D.索引存储
11.在无向图G的邻接矩阵A中,若A[j][i]等于10,则A[i][j] 。
A.小于10 B.等于10 C.大于10 D.不确定
请将答案写在本大题后面的空白页上,请注明题号。
1.(4分)简述算法下面AA的功能
void BB(Lnode *s, Lnode *q) { //设LNode为单向链表的结点数据类型
LNode * p;
p=s;
While (p->next!=q) p=p->next;
p->next=s;
}
void AA(Lnode *pa, Lnode *pb) {
//pa和pb单向循环链表中的两个结点
BB(pa, pb);
BB(pb, pa);
}
2.设计算法,将输入的以-1结束的一串整数建立一不带表头附加结点的单向链表。(7分)
3.请写出循环队列(队列的顺序存储)的数据类型定义和实现算法。(10分)
4.写出用三元组表存储稀疏矩阵的数据类型定义,并写出如下稀疏阵对应的三元组表(以行序为主序)。(6分)
5.写出利用Dijkstra算法求下图中顶点1到其他各顶点间的最短路径的过程。写出必要的步骤。(7分)
6.对于关键字序列(49,38,65,97,76,13,27,49),写出2—路归并排序每趟排序的执行结果。(6分)
7.(10分)如下二叉树,
1)设计两种二叉树的存储结构,并画出该二叉树对于这两种存储结构的存储形式。
2)写出该二叉树的先根、中根、后根遍历次序。
一、填空题
二、单项选择题
7. D 2. GFLC; HEMD;BJPR;INQ;
3.A 4.B 5.C 6.A
7.D 8.C 9.C 10.B 11.B
三、应用题
8. 算法AA的功能是:把单循环链表的pa和pb中间的结点连成一个新的单循环链表;pa和pb之外的结点连成一个新的循环链表。
9.
Typedef struct LNode
{
int data;
Struct LNode *next;
}LNode, *LinkList;
bool ListCreate(LinkList *L)
{
LNode *p = (LNode*)malloc(sizeof(LNode));
LNode *q;
if(p == NULL) return false;
L=p;
int e ;
scanf(("%d",&e);
while(e!=-1)
{
p->data=e;
p->next= (LNode*)malloc(sizeof(LNode));
q=p;
p=p->next;
scanf(("%d",&e);
}
q->next=null;
}
3.
#define MAXSIZE 100;
Typedef struct
{
ElemType base[MAXSIZE];
Int front;
Int rear;
}Queue;
Bool En (Queue &Q, Elemtype e)
{
If((Q.rear+1)%MAXSIZE= =Q.front) return ERROE;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXSIZE;
Return TRUE:
}
Bool Out(Queue &Q, Elemtype & e)
{
If( Q.front= = Q.rear) return ERROR;
E=Q.base[Q.front] ;
Q.front=(Q.front+1)%MAXSIZE ;
Return TRUE :
}
4.
#define MAXSIZE 12500
Typedef struct
{
Int i, j ;
ElemType e;
}Triple;
Typedef struct
{
Triple data[MAXSIZE+1];
Int mu, nu , tu ;
}TSMatrix;
Mu=3 nu=4 tu=4
从1到各终点的带权值和最短路径的求解过程
6.
(49,38,65,97,76,13,27,49)(题中给出的第一个和最后一个都是49)
初始关键字 [49] [38] [65] [97] [76] [13] [27] [49]
一趟归并之后 [38 49] [65 97] [13 76] [27 49]]
二趟归并之后 [38 49 65 97] [13 27 49 76]
三趟归并之后 [13 27 38 49 49 65 76 97]
1)A.顺序存储结构
MAX_TREE_SIZE 100; //二叉树的最大结点数
Typedef TElemType SqBiTree[MAX_TREE_SIZE]; //0号单元存储根节点
SqBiTree bt;
该二叉树对于顺序存储结构的存储形式如下:
B.链式存储结构
Typedef struct BiTNode
{
TelemType data ;
Struct BiTNode *lchild, *rchild ;
}BiTNode, *BiTree ;
该二叉树对于顺序存储结构的存储形式如下:
2)先根序列: R A C D B E F G
中跟序列: C A D R B F E G
后跟序列: C D A F G E B R
1.(2分)已知L是一个带表头的单链表,删除首元素结点的语句序列是 。
2.(3分)数组q[M]存储一个循环队列,first和last分别是首尾指针,如果使元素x进队列的操作语句为“q[last]=x; last=(last+1)%M;”,使元素出队列的操作语句为“e=q[front]; front=(front+1)%M;”。那么,判断队满的条件是 ;判断队空的条件是 。
3.(2分)对于一个具有n个结点的单链表,在已知的结点*p后插入一个新结点的时间复杂度为___________,在给定值为x的结点后插入一个新结点的时间复杂度为_______。
4.(2分)若对线性表的主要操作是存取表中的元素,而极少进行插入和删除,则应选用
存储结构存储该线性表。
5.(2分)广义表(((a,b,(),c),d),e,((f),g))的长度是______,深度是_____。
6.(2分)在堆排序和快速排序中,若原始记录接近正序或反序,则选用_____________;若原始记录无序, 则最好使用______________。
7.(2分)一个图的________________表示法是唯一的,而_________________表示法是不唯一的。
8. (2分)对称矩阵一般采用二维数组存储,为节省存储空间只存储其 。
稀疏矩阵一般采用 存储结构。
9. (2分)双向循环链表中,在p所指结点右侧插入指针s所指结点的语句序列是
。
1、链表不具有的特点是( )。
A、可随机访问任一元素 B、插入删除不需要移动元素
C、不必事先估计存储空间 D、所需空间与线性表长度成正比
2、一个单向简单链表存储的栈,其栈顶指针为top。执行操作( )可将s所指的结点进栈。
A. s->next=top; top=s B. s->next=top->next; top->next=s
C. top->next=s D. s->next=top; top = top->next
3、设有13个值,用它们组成一棵哈夫曼树,则该哈夫曼树共有( )个结点。
A、13 B、12 C、28 D、25
4、若一个系统中,经常进行求子串和串连接操作,串的长度相差悬殊,存在很多短串。则该系统中的串最好选用( )存储结构。
A、定长顺序存储表示 B、堆分配存储表示
C、块链存储表示(节点大小为1) D、块链存储表示(节点大小大于1)
5、在下列有关关键路径的说法中错误的是( )。
A、在AOE网络中可能存在多条关键路径
B、关键活动不按期完成就会影响整个工程的完成时间
C、任何一个关键活动提前完成,那么整个工程将会提前完成
D、所有的关键活动都提前完成,那么整个工程将会提前完成
6、哈希表的平均查找长度( )。
A、与处理冲突方法有关而与表的长度无关
B、与处理冲突方法无关而与表的长度有关
C、与处理冲突方法有关且与表的长度有关
D、与处理冲突方法无关且与表的长度无关
7、在下列排序方法中,关键字比较的次数与记录的初始排列次序无关的是( )。
A、快速排序 B、冒泡排序 C、插入排序 D、选择排序
8、对下图所示的无向图,从V1开始进行广度优先遍历,可得到顶点访问序列( )。
9、在单链表中,若p结点不是末尾结点,在其后插入s结点的操作是( )。
A、s—>next = p;p—>next = s B、s—>next = p—>next;p—>next = s
C、s—>next = p—>next ;p = s D、p—>next =s;s—>next = p
10、设n,m为一棵二叉树上的两个结点,在中序遍历时,n在m前的条件是( )。
A、n在m的右方 B、n是m祖先
C、n在m的左方 D、n是m子孙
11、在数据结构中,从逻辑上可以把数据结构分成( )
A、动态结构和静态结构 B、紧凑结构和非紧凑结构
C、线性结构和非线性结构 D、内部结构和外部结构
12、若线性表元素值均是0 ~ M-1之间的有序整数,无重复元素,其中M是某不太大的整数。最便于插入和删除的存储方式是( )。
A、顺序存储 B、0/1数组a[M] (a[i]==0、1分别表示i不为、为线性表的元素)
C、双向链表 D、单向链表
13、实现任意二叉树的后序遍历的非递归算法而不使用栈结构,最佳方案是二叉树采用( )存储结构。
A、二叉链表 B、广义表存储结构 C、三叉链表 D、顺序存储结构
14、栈和队列的共同点是( )。
A、都是先进先出 B、都是先进后出
C、只允许在端点处插入和删除元素 D、没有共同点
1、(8分)有如下递归过程:
Void reverse( int m)
{
printf( " %d " , m%10 );
if ( m/10 != 0 )
reverse( m/10 );
}
简述此递归算法的功能,并写出调用语句reverse(582)的结果。
2、(8分)树、森林和其对应的二叉树是一一对应的。在实际应用中,树、森林一般转化成二叉树进行存储。
1)画出下面森林对应的二叉树。
3、(8分)以关键字序列{265,301,751,129,937,863,742,694, 76,438}为例,写出执行归并排序算法或快速排序算法的每趟排序结束时,关键字序列的状态。请注明你所用的排序算法名称。
4、(8分)已知序列17,31,13,11,20,35,25,8,4,11,24,40,27
(1)请画出该序列的二叉排序树;
(2)给出在二叉排序树中,查找元素24的查找过程。
5、(8分)假设二叉树BTree采用链接存储结构(二叉链表)进行存储。
1)写出二叉树的链式存储结构的数据类型定义。
2)编写一个算法,输出这个二叉树的所有叶子节点。提示:可基于二叉树的遍历算法写出。
6、(13分)有一个带权无向图G,如下所示:
(1) 画出该图的邻接表存储结构。
(2) 根据该图的邻接表存储结构,从顶点1出发,调用DFS(深度优先搜索)和BFS(广度优先搜索)算法遍历该图,写出可能经过的顶点序列。
(3) 给出采用普里姆算法或克鲁斯卡尔算法构造最小生成树的过程,要求指明你用的是哪个算法。
一、 填空(共19分)
1、(2分) L->next=L->next->next
2、(3分) (last+1)%M= =first或first= =(last+1)%M, last= =first或first= =last
3、(2分) O(1), O(n)
4、(2分) 顺序
5、(2分) 3,4
6、(2分) 堆排序,快速排序
7、(2分) 邻接矩阵,邻接表
8、(2分)上三角中的元或下三角中的元(两个写出一个即可)
9、(2分)s->next=p->next; s->priou=p; p->next->priou=s; p->next=s(答案不唯一)
二、 单项选择题(每题2分,共28分)
1、A 2、A 3、D 4、B 5、C 6、A 7、D 8、A 9、B 10、C 11、C 12、C 13、A 14、C
三、 应用题(共53分)
1、(8分)该算法将整数m从右向左写出。 285
2、( 8分 ) 1)
3、(8分)
归并排序过程如下:
初始状态:265,301,751,129,937,863,742,694,076,438
第一趟:[265],[301],[751],[129],[937],[863],[742],[694],[076],[438]
第二趟:[265,301],[129,751],[863,937],[694,742],[076,438]
第三趟:[129,265,301,751],[694,742,863,937],[076,438]
第四趟:[076,129,265,301,438,694,742,751,863,937,]
快速排序过程略
4、(8分)
5、
Typedef struct BTNode
{ ElemType data;
BTNode * lchild;
BTNode * rchild;
}BTNode, *BTree
Void findleaf( BTree b)
{
if(b= = NULL) return;
If(b -> lchild = = NULL && b -> rchild = =NULL)
Printf ("%c", b -> data);
Else
{ findleaf ( b -> lchild );
findleaf ( b -> rchild );
}
}
6、(13分)
(1)图G的邻接表存储结构如下图所示。(4分)
(2)从顶点1出发,DFS遍历序列为:1,2,3,5,4,6(4分)
BFS遍历序列为:1,2,3,4,5,6
(3)采用克鲁斯卡尔算法构造最小生成树的过程如下所示:(5分)
1.带头结点的单链表head为空的判断条件是 。
2.S[M]存储一个栈,top为栈顶指针。执行操作序列
可将元素x进栈。
3.对于一个具有n个结点的单链表,在已知的结点*p后插入一个新结点的时间复杂度为___________,在给定值为x的结点后插入一个新结点的时间复杂度为__________。
4.在广义表((a,b),c,((d),e),(f,j,(g),(h)))第4个元素的第3个元素是_______。
5.在直接插入和直接选择排序中,若初始数据基本有序,则选用_____________;若初始数据基本反序, 则选用______________。
6. 图的遍历方式有_________________和______________________两种。
1、在线性表的下列存储结构中,读取元素花费时间最少的是( )。
A、单链表 B、双链表 C、循环链表 D、顺序表
2、链表不具有的特点是( )。
A、可随机访问任一元素 B、插入删除不需要移动元素
C、不必事先估计存储空间 D、所需空间与线性表长度成正比
3、假设一个循环队列Q[maxSize]的队头指针为front,队尾指针为rear,队列的最大容量为maxSize,除此之外,该队列再没有其他数据成员,则该队列的队满条件是( )。
A、Q.front = = Q.rear B、Q.front + Q.rear > = maxSize
C、Q.front = =(Q.rear+1)% maxSize D、Q.rear = =(Q.front +1)% maxSize
4、数组q[M]存储一个循环队列,front和rear分别是首尾指针。如果使元素x出队操作的语句为“front=(front+1)%M; x=q[front];”。那么元素x进队的语句是( )。
A. rear=(rear+1)%M; q[rear]=x B. x=q[rear]; rear =( rear +1)%M
C. q[rear+1]=x D. q[(rear +1)%M]=x
5、根据使用频率为5个字符设计的哈夫曼树编码不可能是( )。
A、111, 110, 10, 01, 00 B、000, 001, 010, 011, 1
C、100, 11, 10, 1, 0 D、001, 000, 01, 11, 10
6、下面关于串的的叙述中,哪一个是不正确的?( )
A、串是字符的有限序列 B、空串是由空格构成的串
C、模式匹配是串的一种重要运算 D、串既可以采用顺序存储,也可以采用链式存储
7、在任何一棵二叉树中,如果结点a有左孩子b、右孩子c,则在结点的先序序列、中序序列、后序序列中,( )。
A、结点b一定在结点a的前面 B、结点a一定在结点c的前面
C、结点b一定在结点c的前面 D、结点a一定在结点b的前面
8、对矩阵压缩存储是为了( )。
A、方便运算 B、节省空间 C、方便存储 D、提高运算速度
9、如图1所示的二叉树是由某森林转换而来的,则在原森林中共有( )树,共有( )叶子。
A、1 B、2 C、3 D、大于3
10、对图2所示的无向图,从V1开始进行深度优先遍历,可得到顶点访问序列( )。
A、1, 2, 4, 3, 5, 7, 6 B、1, 2, 4, 3, 5, 6, 7
C、1, 2, 4, 5, 6, 3, 7 D、1, 2, 3, 4, 5, 7, 6
11、关键路径是事件结点网络中( )。
A、从源点到汇点的最长路径 B、从源点到汇点的最短路径
C、最长的回路 D、最短的回路
12、快速排序在( )情况下最不利于发挥其长处。
A、要排序的数据量太大 B、要排序的数据中含有多个相同值
C、要排序的数据已基本有序 D、要排序的数据个数为奇数
13、数据表A中有100000个元素,如果仅要求求出其中最大的10个元素,则采用( )方法最节省时间。
A、堆排序 B、希尔排序 C、快速排序 D、直接选择排序
14、在二叉排序树中,凡是新插入的结点,都是没有( )的。
A、孩子 B、关键字 C、平衡因子 D、赋值
15、二叉树和度为2的树的相同之处包括( )。
A、每个结点都要一个或两个孩子结点 B、至少有一个根结点
C、至少有一个度为2的结点 D、每个结点至多只有一个双亲结点
1、(6分)有如下递归过程:
void print( int w)
{
int i;
if(w!=1)
{ print(w-1);
for( i = 0; i <= w; i++)
printf( “%3d”,w);
printf(“\n”);
}
}
写出调用语句print(4)的结果。
2、(18分)在实际应用中,常用的数据结构包括线性表、树、图,其中线性表应用最为广泛。1)请给出线性表、树、图的定义;2)请说明他们在计算机中如何存储(可不必给出其数据类型定义);3)请比较这三种数据结构,并说明他们各自的应用领域。
3、(8分)设计算法,删除采用顺序存储结构的线性表中的重复元素。
4、(8分)以关键字序列{35,18,56,42,37,81,95,21,77,26,54}为例,写出执行快速排序算法或希尔排序算法或归并排序算法的各趟排序结束时,关键字序列的状态。请注明你所用的排序算法名称。
5、(8分)若哈希表(Hash)的地址范围为[0,9],哈希函数为H(key)=(key2+2)MOD9,并采用链地址法处理冲突,请画出7、4、5、3、6、2、8、9依次插入哈希表以后该哈希表的状态。
6、(10分)有一个带权无向图G,如下所示:
(1) 画出该图的邻接矩阵和邻接链表存储结构。
(2) 给出采用克鲁斯卡尔算法或普里姆算法构造最小生成树的过程。
一、 填空(共12分)
1、(2分) head->next=NULL
2、(2分) S[top]=x; top++;
3、(2分) O(1), O(n)
4、(2分) 子表(g)
5、(2分) 直接插入,直接选择
6、(2分) DFS深度有先,BFS广度有先
二、 单项选择题(每题2分,共30分)
1、D 2、A 3、C 4、A 5、C
6、B 7、C 8、B 9、A,C 10、A
11、A 12、C 13、A 14、A 15、D
三、 应用题(共58分)
1、(6分)
1
2 2
3 3 3
4 4 4 4
2、( 18分 )
1)给出这三种数据结构的定义;6分,每个定义2分
2)说明他们在计算机中如何存储(可不必给出其数据类型定义);6分
3)请比较这三种数据结构-----3分
说明他们各自的应用领域-----2分
3、(8分)
Void A(LinkList * &head) //head是无表头附加结点的单链表
{
LinkList * p = head -> next, *q, *pre, *r;
While(p != NULL )
{ q = p -> next; pre = p; // *pre指向 *q 结点的前驱
While( q!= NULL)
{ if ( p -> data = = q -> data )
{ r = q; pre -> next = q -> next;
q=q -> next; free ( r ); }
else
{ pre = q; q = q -> next ; }
}
p = p -> next ;
}
}
4、(8分)
归并排序过程如下:
初始状态:35,18,56,42,37,81,95,21,77,26,54
第一趟:18, 35; 42,56; 37,81; 21, 95; 26, 77;54
第二趟:18, 35,42, 56; 21,37, 81, 95; 26, 54, 77
第三趟:18, 21, 35, 37, 42, 56, 81, 95; 26, 54, 77
第四趟:18, 21, 26, 35, 37, 42, 54, 56, 77, 81, 95
希尔排序算法、快速排序算法的执行过程略。
5、
6、
(1)图G的邻接矩阵存储结构如下图所示。(3分 )
图G的邻接链表存储结构略。(3分 )
(2) 采用克鲁斯卡尔算法造最小生成树的过程如下所示(4分)
1、设 n 为正整数。试确定下列各程序段中前置以记号@的语句的频度。
(1)
i = 1;
k = 0;
while(i <= n-1)
{
@ k += 10*i;
i++;
}
(2)
k = 0;
for(i = 1; i <= n; i++)
{
for(j = i; j <= n; j++)
@ k++;
}
(3)
for(i = 1; i <= n; i++)
{
for(j = 1; j <= i; j++)
{
for(k = 1; k <= j; k++)
@ x += delta;
}
}
2、假设n为2的乘幂,并且 n > 2,试求下列算法的时间复杂度及变量 count 的值(以n的函数形式表示)并写出计算过程。
int Time(int n)
{
int count = 0;
int x = 2;
while(x < n/2)
{
x *= 2;
count ++;
}
return (count);
}//Time
程序作业
已知 k 阶斐波那契序列的定义为:
试编写求 k 阶斐波那契序列的第 m 项值的函数算法,k 和 m 均以值调用的形式在函数参数表中出现。请写出算法的时间复杂度。
1.
Status Fibonacci(int k, int m, int &f)
2. /* 求k阶斐波那契序列的第m项的值f */
3. {
4. int sum,i,j,e[100];
5. if(k < 2||m < 0) return ERROR; /**异常处理**/
6. /**
7. 根据k阶斐波那契序列的定义:
8. K阶斐波那契数列的前K-1项均为0,
9. 第k项为1,以后的每一项都是前K项的和
10. **/
11. if(m < k-1)
12. f = 0;
13. else if(m == k-1)
14. f = 1;
15. else{
16. for(i = 0;i < k-1;i++)
17. e[i] = 0; //K阶斐波那契数列的前K-1项均为0
18. e[k-1] = 1; //第k项为1
19. for(i = k;i <= m;i++){
20. sum = 0;
21. for(j = i-k;j <= i;j++)//以后的每一项都是前k项的和
22. sum += e[j];
23. e[i] = sum; //将以后的每一项的值存进数组e中
24. }
25. f = e[m]; //求k阶斐波那契序列的第m项的值f
26. }
27. return OK;
28. }
int ListInsert(LinkList &L,int i,int e)
{ // 在不设头结点的单链线性表L中第i个位置之前插入元素e
int j=1; // 计数器初值为1
LinkList s,p=L; // p指向第1个结点
if(i<1) // i值不合法
return 0;
s=(LinkList)malloc(sizeof(LNode)); // 生成新结点,以下将其插入L中
s->data=e; // 给s的data域赋值e
if(i==1) // 插在表头
{ s->next=L; // 新结点指向原第1个结点
L=s; // L指向新结点(改变L)
}
else
{ // 插在表的其余处
while(p&&j<i-1) // 寻找第i-1个结点
{ j++; // 计数器+1
p=p->next; // p指向下一个结点
}
if(!p) // i大于表长+1
return 0; // 插入失败
s->next=p->next; // 新结点指向原第i个结点
p->next=s; // 原第i-1个结点指向新结点
}
return 1; // 插入成功
}
//不带头结点的删除运算
int ListDelete(LinkList &L,int i,int &e)
{ // 在不设头结点的单链线性表L中,删除第i个元素,并由e返回其值
int j=1; // 计数器初值为1
LinkList q,p=L; // p指向第1个结点
if(!L) // 表L空
return 0; // 删除失败
else if(i==1) // 删除第1个结点
{ L=p->next; // L由第2个结点开始(改变L)
e=p->data; // 将待删结点的值赋给e
free(p); // 删除并释放第1个结点
}
else
{ while(p->next&&j<i-1) // 寻找第i个结点,并令p指向其前驱
{ j++; // 计数器+1
p=p->next; // p指向下一个结点
}
if(!p->next||j>i-1) // 删除位置不合理
return 0; // 删除失败
q=p->next; // q指向待删除结点
p->next=q->next; // 待删结点的前驱指向待删结点的后继
e=q->data; // 将待删结点的值赋给e
free(q); // 释放待删结点
}
return 1; // 删除成功
}
#include
#include
typedef struct node
{
int data;
struct node *next;
}*Listlink;
/*前插法创建单链表*/
void qian_create(Listlink *head,int n)
{
int i;
Listlink p;
*head=(Listlink )malloc(sizeof(struct node));
(*head)->next=NULL;/*建立头结点*/
printf("input %d numbers:\n",n);
for(i=0;i<n;i++)
{
p=(Listlink)malloc(sizeof(struct node));
scanf("%d",&(p->data));
p->next=(*head)->next;
(*head)->next=p;
}
}
/*后插法创建单链表*/
void hou_create(Listlink *head,int n)
{
int i;
Listlink p,q;
*head=(Listlink )malloc(sizeof(struct node));
(*head)->next=NULL;/*建立头结点*/
q=*head;
for(i=0;i<n;i++)
{
p=(Listlink)malloc(sizeof(struct node));
scanf("%d",&(p->data));
p->next=q->next;
q->next=p;
q=p;
}
}
void print_list(Listlink head)
{
Listlink p;
p=head->next;
while(p!=NULL)
{
printf(" %d",p->data);
p=p->next;
}
}
main()
{
Listlink la,lb,lc;
puts("houcha:");
hou_create(&lb,10);
puts("qiancha:");
qian_create(&la,10);
print_list(la);
print_list(lb);
getchar();
}
#include
#include
#define MAXSIZE 20
//二叉树结点的结构体表示形式
typedef struct node
{
char data;
struct node* left,*right;
}BTree;
//栈的结构体表示形式
typedef struct stackelem
{
BTree* a[MAXSIZE];
int top;
}Stack;
//队列的结构体的表示形式
typedef struct queueelem
{
BTree* b[MAXSIZE];
int front,rear;
}Queue;
//创建二叉树,利用递归的方法
BTree* Create()
{
char ch;
scanf("%c",&ch);
getchar();
if (ch=='#')
{
return NULL;
}
else
{
BTree* btree=(BTree*)malloc(sizeof(BTree));
if (btree==NULL)
{
return NULL;
}
btree->data=ch;
btree->left=Create();
btree->right=Create();
return btree;
}
}
//求二叉树的高度,递归实现
int Height(BTree* bt)
{
int depth1,depth2;
if (NULL==bt)
{
return 0;
}
else
{
depth1=Height(bt->left);
depth2=Height(bt->right);
if (depth1>depth2)
{
return (depth1+1);
}
else
{
return (depth2+1);
}
}
}
int Width(BTree *T)//二叉树宽度
{
int static n[10];//向量存放各层结点数
int static i=1;
int static max=0;//最大宽度
if(T)
{
if(i==1) //若是访问根结点
{
n[i]++; //第1层加1
i++; //到第2层
if(T->left)//若有左孩子则该层加1
n[i]++;
if(T->right)//若有右孩子则该层加1
n[i]++;
}
else
{ //访问子树结点
i++; //下一层结点数
if(T->left)
n[i]++;
if(T->right)
n[i]++;
}
if(max<n[i])max=n[i];//取出最大值
Width(T->left);//遍历左子树
i--; //往上退一层
Width(T->right);//遍历右子树
}
return max;
}
//层次遍历二叉树,用队列来实现
void TraversalOfLevel(BTree* bt)
{
Queue q;
q.front=q.rear=0;
if (bt!=NULL)
{
printf("%c ",bt->data);
}
q.b[q.front]=bt;
q.rear=q.rear+1;
while (q.front<q.rear)
{
bt=q.b[q.front];
q.front=q.front+1;
if (bt->left!=NULL)
{
printf("%c ",bt->left->data);
q.b[q.rear]=bt->left;
q.rear=q.rear+1;
}
if (bt->right!=NULL)
{
printf("%c ",bt->right->data);
q.b[q.rear]=bt->right;
q.rear=q.rear+1;
}
}
}
int leafcount(BTree* root)//统计叶子结点个数
{
if(root==NULL) return 0 ;
else
{
if(!root->right&&!root->left) return 1;
else return leafcount(root->left)+leafcount(root->right);
}
}
int CountNode (BTree *t) //节点总数
{
int num;
if (t == NULL)
num = 0;
else
num = 1 + CountNode (t->left) + CountNode (t->right);
return (num);
}
BTree *copy(BTree *p) // 复制一棵二叉树
{
BTree *temp;
if(p==NULL)
return NULL;
temp=(BTree *)malloc(sizeof(BTree));
temp->data=p->data;
temp->left=copy(p->left);
temp->right=copy(p->right);
return temp;
}
/* 判断两棵二叉树是否相似的递归算法 */
int Similar(BTree *t1, BTree *t2)
{
if(t1==NULL&&t2==NULL) return 1;
if(t1&&t2)
{
if(Similar(t1->left,t2->left)&&Similar(t1->right,t2->right))
{
return 1;
}
}
return 0;
}
int CompTree(BTree *tree1,BTree *tree2)//二叉树是否相等
{
if (!tree1 && !tree2)
{
return 1;
}
else if (tree1->data == tree2->data &&
CompTree(tree1->left, tree2->left) &&
CompTree(tree1->right, tree2->right))
{
return 1;
}
else
{
return 0;
}
}
int main()
{
BTree* btr=Create();
printf("叶子结点个数为:\n");
int leafgs=leafcount(btr);
printf("%d \n",leafgs);
printf("结点总数为:\n");
int countn=CountNode(btr);
printf("%d \n",countn);
printf("度为1的结点个数为:%d\n",countn-2*leafgs+1);
printf("度为2的结点个数为:%d\n",leafgs-1);
printf("二叉树的高度:\n");
int Hgt=Height(btr);
printf("%d \n",Hgt);
printf("二叉树的宽度:\n");
int Wdh=Width(btr);
printf("%d \n",Wdh);
printf("层次遍历二叉树:\n");
TraversalOfLevel(btr);
printf("\n");
printf("复制的二叉树为:\n");
BTree * cp=copy(btr);
TraversalOfLevel(cp);
printf("\n");
if(Similar(btr,cp)==1)
printf("此两二叉树相似\n");
else printf("此两二叉树不相似\n");
if(CompTree(btr,cp)==1)
printf("此两二叉树相等\n");
else printf("此两二叉树不相等\n");
return 0;
}
一、 选择题
设有一个输入数据的序列是 { 46, 25, 78, 62, 12, 80 }, 试画出从空树起,逐个输入各个数据而生成的二叉搜索树。
已知一棵二叉树的前序遍历的结果序列是ABECDFGHIJ,中序遍历的结果是EBCDAFHIGJ,试写出这棵二叉树的后序遍历结果。
设给定一个权值集合W=(3,5,7,9,11),要求根据给定的权值集合构造一棵哈夫曼树并计算哈夫曼树的带权路径长度WPL。
对于图6所示的有向图若存储它采用邻接表,并且每个顶点邻接表中的边结点都是按照终点序号从小到大的次序链接的,试写出:
(1) 从顶点①出发进行深度优先搜索所得到的深度优先生成树;
(2) 从顶点②出发进行广度优先搜索所得到的广度优先生成树;
6. 已知一个图的顶点集V和边集E分别为:
V={1,2,3,4,5,6,7};
E={<2,1>,❤️,2>,❤️,6>,<4,3>,<4,5>,<4,6>,<5,1>,<5,7>,<6,1>,<6,2>,<6,5>};
若存储它采用邻接表,并且每个顶点邻接表中的边结点都是按照终点序号从小到大的次序链接的,按主教材中介绍的拓朴排序算法进行排序,试给出得到的拓朴排序的序列。
7. 已知一个图的顶点集V各边集G如下:
V = {0,1,2,3,4,5,6,7,8,9};
E = {(0,1),(0,4),(1,2),(1,7),(2,8),(3,4),(3 ,8),(5,6),(5,8),(5,9),(6,7),(7,8),(8,9)}
当它用邻接矩阵表示和邻接表表示时,分别写出从顶点V0出发按深度优先搜索遍历得到的顶点序列和按广度优先搜索遍历等到的顶点序列。
假定每个顶点邻接表中的结点是按顶点序号从大到小的次序链接的。
8. 设无向图G(所右图所示),要求给出该图的深度优先和广度优先遍历的序列并给出该图的最小生成树。
9. 一个线性表为B=(12,23,45,57,20,03,78,31,15,36),设散列表为HT[0…12],散列函数为H(key)= key % 13并用线性探查法解决冲突,请画出散列表,并计算等概率情况下查找成功的平均查找长度。
10. 设一组初始记录关键字集合为(25,10,8,27,32,68),散列表的长度为8,散列函数H(k)=k mod 7,要求分别用线性探测和链地址法作为解决冲突的方法设计哈希表并计算平均查找长度。
11. 已知一组记录的排序码为(46,79,56,38,40,80, 95,24),写出对其进行快速排序的每一次划分结果。
12. 设一组初始记录关键字序列为(19,21,16,5,18,23),要求给出以19为基准的一趟快速排序结果以及第2趟直接选择排序后的结果。
13. 依次把结点(34,23,15,98,115,28,107)插入到初始状态为空的平衡二叉排序树中,使得在每次插入后保持该树仍然是平衡二叉树。请依次画出每次插入后所形成的的平衡二叉排序树。
5、
DFS:①②③④⑤
BFS:②③④⑤①
6、
4 3 6 5 7 2 1
7、
11、
24,40,38,46,56,80,95,79
24,40,38,46,56,80,95,79
24,38,40,46,56,80,95,79
24,38,40,46,56,79,80,95
一、 选择题
①、由装载因子0.7,数据总数7个,所以储空间长度为10。所以,构造的散列表的哈希地址为:
H(7)=(73)MOD7=0
H(8)=(83)MOD7=3
H(11)=(113)MOD7=5
H(18)=(183)MOD7=5
H(9)=(93)MOD7=6
H(14)=(143)MOD7=0
H(30)=(30*3)MOD7=6
根据哈希地址可以得出如下图所示的哈希表。
②、平均查找长度
查找成功的平均查找长度:ASL成功 =(1+1+1+1+2+3+3)/7=12/7。
查找不成功的平均查找长度:ASL不成功 =(3+2+1+2+1+5+4)/7=18/7。
2. 已知无向网G的邻接矩阵如下图所示,顶点依次是V1,V2,V3,V4,V5,V6,V7,V8,要求:
(1) 请画出该网。
(2) 按克鲁斯卡尔算法给出网G的最小生成树的生成过程。
(1)、无向网。
(4)
(2)、克鲁斯卡尔算法生成最小生成树的过程。