i=i+1
③s=s+i
④returni
答:
11次
2(2n)^1/2次
3(2n)^1/2-1次
41次
5O(n^1/2)
第2章数组结构
一、选择题
1.线性表是一个A。
A.有限序列,可以为空B.有限序列,不能为空
C.无限序列,可以为空D.无限序列,不能为空
2.下面关于线性表的叙述中,错误的是B。
A.线性表采用顺序存储,必须占用一片连续的存储单元
B.线性表采用顺序存储,便于进行插入和删除操作
C.线性表采用链接存储,不必占用一片连续的存储单元
D.线性表采用链接存储,便于进行插入和删除操作
3.某线性表采用顺序存储结构,每个元素占4个存储单元,首地址为100,则第12个元素的存储地址为A。
A.144B.145C.147D.148
4.若长度为n的顺序存储结构线性表,删除第i个数据元素,需要向前移动A个数据元素。
A.n-iB.n+iC.n-i-1D.n-i+1
5.若长度为n的顺序存储结构线性表,在第i个位置插入一个元素,需要依次向后移动D个元素。
A.n-iB.n+iC.n-i-1D.n-i+1
6.一个顺序表所占存储空间的大小与D无关。
A.顺序表长度B.结点类型
C.结点中个数据域的类型D.结点的存放次序
7.以下叙述不正确的是D。
A.数据的逻辑结构包括线性和非线性结构,非线性结构包括树和图两种。
B.数据的逻辑结构主要指元素间的关系,与计算机的存储和处理无关
C.数据的存储结构是指数据在计算机中的存储方式,主要包括顺序和链式两种
D.对于给定的n个元素,可以构造出的逻辑结构有顺序表和链表两种
8.某线性表采用顺序存储结构,则下列叙述正确的是B。
A.删除顺序表第i个元素和在第i位置插入一个元素所需移动的元素个数一样
B.删除顺序表第i个元素和在第i位置插入一个元素的时间复杂度一样
C.删除顺序表第i个元素和取第i元素的值的时间复杂度一样
D.在顺序表表头插入和表尾插入的时间复杂度一样
9.对线性表,在下列情况下应当采用顺序表表示的是A。
A.经常需要随机地存取元素B.经常需要进行插入和删除操作
C.表中每个元素需要的字节数比较大D.表中的元素个数不变
10.在含有n个元素的顺序表中,算法的时间复杂度是O
(1)的操作是___A___。
A.访问第i个元素(1≤i≤n)和求第i个元素的直接前驱(2≤i≤n)
B.在第i个元素后插入一个新元素(1≤i≤n)
C.删除第i个元素(1≤i≤n)
D.将n个元素从小到大排序
二、填空题
1.一个一维数组(列表)A的长度为500,起始(A[0])地址为2000,每个元素占4个字节,则A[80]的地址是2320。
2.一个4*6的二维数组A,每个元素占4个字节,假设该数组起始元素A(1,1)的地址是110,若以行为主存储,则A(3,5)的地址是174;若以列为主存储,A(3,5)的地址是182。
3.以顺序存储结构实现的线性表简称为顺序表,它要求存储空间必须是连续的,并以下标来体现元素之间的关系,在顺序表中访问第i个元素的时间复杂度为O
(1),因此,顺序表也称为随机存取的数据结构。
以链式存储结构实现的线性表称为链表。
其存储空间可以是不连续的,以指针来体现元素之间的关系。
在链表中访问第i个元素的时间复杂度为O(n),因此,链表也称为顺序访问的数据结构。
三、算法设计题
1.设有一个顺序表L,其元素为整型数据,编写一个要求时间复杂度为O(n)、空间复杂度为O
(1)的算法,将L中所有小于0的整数放在前半部分,大于0的整数放在后半部分。
提示:
从L的两端查找,前端找大于0的数据,后端找小于0的数据,然后将两位置的数据交换。
L=[1,2,3,4,5,6,7,8,9,10,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]
n=len(L)
print("原顺序表:
\n{}".format(L))
j=0
k=0
foriinrange(n):
ifL[i]<0:
k=L[i]
L[i]=L[j]
L[j]=k
j+=1
else:
continue
print("排序后顺序表:
\n{}".format(L))
2.在一个有序列表中查找元素x,当被查元素x小于列表中某个元素时就可停止。
请编写一个函数实现上述查找,并分析此查找在最好情况、最坏情况以及平均情况下的性能。
deffound(L,x):
print("查找元素")
foriinL:
ifx>iorx==i:
print("元素x大于或等于{},程序继续".format(i))
continue
else:
print("元素x小于{},程序停止".format(i))
break
if__name__=="__main__":
x=eval(input("请输入要查找的元素x:
"))
L=[1,2,3,4,5,6,7,8,9]
found(L,x)
3.已知一个n*n的二维数组a已经以行为主存放在一个大小为n2的一维数组b中,编写一个函数计算此二维数组的主对角线元素之和。
count(b,n)
defcount(b,n):
x=0
i=0
whileTrue:
x+=b[i]
i+=n+1
ifi>len(b):
break
print("主对角线元素之和为:
%d"%x)
if__name__=="__main__":
a=[[1,2,3],[4,5,6],[7,8,9]]
b=[]
n=len(a)
print("二维数组A为:
")
foriinrange(n):
forjinrange(n):
b.append(a[i][j])
print("%d"%a[i][j],end='\t')
print()
print("存放在一维数组b中为:
")
print(b)
count(b,n)
4.有一值为整型、长度为n的顺序表(列表),写一个函数,计算该顺序表所有元素的平均值,并输出所有大于平均值的元素。
defAverage(L,n):
nsum=0
foriinrange(n):
nsum+=L[i]
average=nsum/n
print("平均数为:
%d"%average)
print("所有大于平均值的元素为:
")
foriinL:
ifi>average:
print(i,end='')
else:
continue
if__name__=="__main__":
L=[1,354,56,57,2,8,9,46,767,678]
n=len(L)
Average(L,n)
第3章链表
一、选择题
1.以下关于链式存储结构的叙述中,C是不正确的。
A.结点除自身信息外还包括指针域,因此空间利用率小于顺序存储结构
B.逻辑上相邻的结点物理上不必邻接
C.可以通过计算直接确定第i个结点的存储地址
D.插入、删除运算操作方便,不必移动结点
2.在下列存储结构中,最适合实现在线性表中进行随机访问的是A。
A.数组B.双向链表C.单向链表D.循环链表
3.与单链表相比,双链表的优点之一是D。
A.可以由最后一个结点找到头结点B.可随机访问
C.插入、删除操作更加简单D.访问前驱结点更加方便
4.如果对线性表的运算只有2种,即删除第一个元素,在最后一个元素的后面插入新元素,则最好使用D。
A.顺序表B.单链表C.双向链表D.具有表尾指针的循环单链表
5.在表头指针为head且表长大于1的单向循环链表中,指针p指向表中的某个结点,若p.next.next==head,则D。
A.p指向头结点B.p指向尾结点
C.p所指结点的直接后继是头结点D.p所指结点的直接后继是尾结点
6.带表头附加结点的单链表head为空的判断条件是B。
A.head==None#不带头结点的空链表
B.head.next==None
C.head.next==head
D.head!
=None
7.一个单链表中,若要在指针s所指结点的后面插入一个由指针P所指向的结点,则执行D。
A.s.next=pp.next=s.next;
B.p.next=s.nexts=p
C.s.next=p.nextp.next=s
D.p.next=s.nexts.next=p
8.对线性表,在下列情况下应当采用链表表示的是B。
A.经常需要随机地存取元素
B.经常需要进行插入和删除操作
C.表中元素需要占据一片连续的存储空间
D.表中的元素个数不变
9.如果最常用的操作是取第i个结点及前驱,则采用A存储方式最节省时间。
A.顺序表B.双链表C.单循环链表D.单链表
10.从一个具n个结点的单链表中查找其值等于x的结点时,在查找成功的情况下,需平均比较D个结点。
A.nB.n/2C.(n-1)/2D.(n+1)/2
11.在单链表中,指针p指向元素为x的结点,实现删除x的后继的语句是B。
A.p=p.nextB.p.next=p.next.next
C.p.next=pD.p=p.next.next
12.循环链表的主要优点是D。
A.不再需要头指针了
B.已知某个结点的位置后,能很容易找到它的直接前驱结点
C.在进行删除操作后,能保证链表不断开
D.从表中任一结点出发都能遍历整个链表
二、填空题
1.一个单链表结构中,每个结点都包含有两个域,称为数据域和指针域。
2.已知一个双向链表(指针域名为next和prior)中间局部如下图所示,
现要求将p所指的结点插入到x和y结点之间(即p所指结点后面),其操作步骤为:
p.next=q.next;p.prior=q;
q.next=p;p.next.prior=p;
2.已知L是不带头结点的单链表,阅读下列函数,回答问题。
deffun(L):
#L是不带头结点的单链表的头指针
if(L!
=None&&L.next!
=None):
#语句1
q=L
L=L.next
p=L
while(p.next!
=None):
#语句5
p=p.next
p.next=q
q.next=None
returnL;
(1)说明该函数执行的条件,即语句1的功能
Len(L)>1
(2)说明语句5(即while循环)的功能
查找尾结点
(3)若链表L的初始状态如下图,画出执行上述函数后的链表L的示意图。
三、算法设计题
1.编写一个函数,实现从单链表中查找出所有元素的最大值,该值由函数返回。
deffun(L):
ifL.next=None:
return0
Max=L.next.data
p=L.next.next
whilep!
=None:
ifp.data>max:
max=p.data
p=p.next
returnmax
2.编写一个函数,实现单链表中删除一个最小值节点的算法(假设该链表中每个节点的值不重复)。
deffun1(L):
ifL.next=None:
returnNone
ptr=L.next
p=L.next.next
whilep!
=None:
ifp.dataptr=p
p=p.next
p=L
Whilep.next!
=ptr:
p=p.next
P.next=p.next.next#p.next=ptr.next
3.假设有一个循环链表的长度大于1,且表中既无头结点也无头指针。
已知s为指向链表某个结点的指针,编写算法在链表中删除指针s所指结点的前驱结点。
deffun(s):
p=s.next
Whilep.next.next!
=s:
p=p.next
p.next=s
第4章栈+第5章队列
一、选择题
1.有5个元素a,b,c,d,e依次进栈,允许任何时候出栈,则可能的出栈序列是C。
A.baecdB.dceabC.abedcD.aebcd
2.下列有关递归的叙述,不正确的是B。
A.在计算机系统内,执行递归函数是通过自动使用栈来实现的。
B.在时间和空间效率方面,递归算法比非递归算法好。
C.递归函数的求解过程分为递推(进栈)和回推(出栈)两个阶段。
D.在递归函数中必须有终止递归的条件。
3.栈和队列均属于哪一种逻辑结构A。
A.线性结构B.顺序结构C.非线性结构D.链表结构
4.设输入元素为1、2、3、P和A,输入次序为123PA,元素经过栈后得到各种输出序列,则可以作为高级语言变量名的序列有B种。
A.4B.5C.6D.7
5.一个队列的入队序列为a,b,c,d,则该队列的输出序列是B。
A.dcbaB.abcdC.adcbD.cbda
6.在一个链式队列中,假设f和r分别为队头和队尾指针,则插入s所指结点的运算是B。
A.f.next=s;f=s;B.r.next=s;r=s;
C.s.next=s;r=s;D.s.next=f;f=s;
7.如果5个元素出栈的顺序是1、2、3、4、5,则进栈的顺序可能是C。
A.3、5、4、1、2B.1、4、5、3、2
C.5、4、1、3、2D.2、4、3、1、5
8.已知一个栈的进栈序列为1,2,3,…,n,其出栈输出序列是p1,p2,p3,…,pn。
若p1=3,则p2的值D。
A.一定是2B.一定是1C.可能是1D.可能是2
9.以1,2,3,…,n的顺序进队列,则可能的出队序列有A种。
A.1B.nC.n(n+1)/2D.
10.在计算递归函数时,如不用递归过程,应借助于B这种数据结构。
A.线性表B.栈C.队列D.双向队列
二、填空题
1.栈和队列是一种特殊的线性表,其特殊性体现在是运算受限线性表。
设现有元素e1,e2,e3,e4,e5和e6依次进栈,若出栈的序列是e2,e4,e3,e6,e5,e1,则栈S的容量至少是3。
2.顺序循环队列中,设队头指针为front,队尾指针为rear,队中最多可有MAX个元素,采用少用一个存储单元的方法区分队满与队空问题,则元素入队列时队尾指针的变化为
rear=(rear+1)%MAX;元素出队列时队头指针的变化为front=(front+1)%MAX;队列中的元素个数为 (rear-front+MAX)%MAX 。
队满的判别条件为为(rear+1)%MAX==front,队空的判别条件为front==rear。
3.一个中缀表达式a+b*(a+c)-c/d的前缀表达式为-+a*b+ac/cd,后缀表达式为abac+*+cd/-。
一个后缀表达式21+42-*3+的值为9。
4.下列函数的功能是求n^2+(n-1)^2+(n-2)^2+……+1的和。
defsum(n):
ifn==0:
return0
else:
returnsum(n-1)+n*n
5.下列算法的功能判断输入的字符串是否是回文。
deffunc():
creatstack(S)#初始化构造一个空栈S
creatqueue(Q)#初始化构造一个空队列Q
str=input(“输入一个字符串:
”)
forchinstr:
push(ch)
enqueue(ch)
whilenotisempty(S):
a=pop()
b=dequeue()
ifa!
=b:
return0
return1
三、解答题
1.用一维数组a[7]顺序存储一个循环队列,队首和队尾指针分别用front和rear表示,当前队列中已有5个元素:
22,30,16,36,58,其中22是队首,front值为5,请画出对应的存储状态图,当连续做两次出队运算后,再做两次入队运算,让元素80,55依次进队,请再画出对应的存储状态图。
2.用一个带头结点的循环链表来表示循环队列,且该队列只设尾指针。
编写初始化、入队、出队操作算法。
classQnode:
def__init__(self,data,next=None):
self.data=data
self.next=None
rear=Qnode()
rear.next=rear
defenqueue(item):
globalrear
newQueue=Qnode()
newQueue.data=item
newQueue.next=rear.next
rear.next=newQueue
rear=newQueue
defdequeue(item):
globalrear
ifrear.next=rear:
print(“队列已空!
”)
else:
item=rear.next.data
rear.next=rear.next.next
returnitem
第5章树形结构
一、选择题
1.按照二叉树定义,具有3个结点的二叉树共有C种形态。
(A)3(B)4(C)5(D)6
2.具有五层结点的完全二叉树至少有D个结点。
(A)9(B)15(C)31(D)16
3.以下有关二叉树的说法正确的是B。
(A)二叉树的度为2(B)一棵二叉树的度可以小于2
(C)至少有一个结点的度为2(D)任一结点的度均为2
4.已知二叉树的后序遍历是dabec,中序遍历是debac,则其前序遍历是D。
(A)acbed(B)decab(C)deabc(D)cedba
5.将一棵有1000个结点的完全二叉树从上到下,从左到右依次进行编号,根结点的编号为1,则编号为49的结点的右孩子编号为B。
(A)98(B)99(C)50(D)没有右孩子
6.对具有100个结点的二叉树,若有二叉链表存储,则其指针域共有D为空。
说明:
n=n0+n1+n2
指针域为空的个数:
2*n0+n1=n0+n1+n2+1=101
(A)50(B)99(C)100(D)101
7.设二叉树的深度为h,且只有度为1和0的结点,则此二叉树的结点总数为C。
(A)2h(B)2h-1(C)h(D)h+1
8.对一棵满二叉树,m个树叶,n个结点,深度为h,则D。
(A)n=h+m(B)h+m=2n(C)m=h-1(D)n=2h-1
9.某二叉树的先序序列和后序序列正好相反,则下列说法错误的是A。
(A)二叉树不存在
(B)若二叉树不为空,则二叉树的深度等于结点数
(C)若二叉树不为空,则任一结点不能同时拥有左孩子和右孩子
(D)若二叉树不为空,则任一结点的度均为1
10.对二叉树的结点从1开始进行编号,要求每个结点的编号大于其左右孩子的编号,同一结点的左右孩子中,其左孩子的编号小于其右孩子的编号,可采用C遍历实现编号。
(A)先序(B)中序(C)后序(D)层序
11.一个具有1025个结点的二叉树的高h为C。
(A)10(B)11(C)11~1025(D)10~1024
12.设n,m为一棵二叉树上的两个结点,在中序遍历时,n在m前的条件是C。
(A)n在m右方(B)n是m祖先
(C)n在m左方(D)n是m子孙
13.实现对任意