1.设单链表中指针p指向结点A,若要删除A的后续结点(假设A存在后续结点),则需要修改指针的操作为____p->next = p->next->next______
结点A | A的后续结点 | p->next->next | 改变前 | |
p | 删除 | p->next | 改变后 |
2.在有n个结点的顺序表上做插入、删除结点运算的时间复杂度为( B )
A.O(1) B.O(n) C.O(n^2) D.O(log2n)
顺序表的插入:
1.判断插入位置 i 是否合法,i的合法范围是[1,n+1],若不合法返回ERROR
2.判断顺序表的存储空间是否已满,若满则返回ERROR
3.将第 n 个至 i 个位置的元素一次向后移动一个位置,空出第 i 个位置
4.将要插入的新元素e放入第 i 个位置
5.表长加 1
Status ListInsert(SqList &L,int i,ElemType e)
{//在顺序表L中第 i 个位置插入一个新元素 e ,i值的合法范围是[1,L.length+1]
if(i<1 || i>L.length+1) return ERROR; //i 值不合法
if(L.length==MAXSIZE) return ERROR; //当前存储空间已满
for(j=L.length-1;j>=i;j--)
L.elem[j+1] = L.elem[j];
L.elem[i-1] = e;
++L.length; //表长+1
return OK;
}
由此可知,其时间复杂度为O(n)
顺序表的删除
1.判断删除位置 i 是否合法,i 的范围为[1,n],若不合法返回ERROR
2.将第 i +1 至 n 的元素一次向前移动一个位置,i = n 时无需移动
3.表长减
Status ListDelete(SqList &L,int i)
{
if(i<1 || i>L.length) return ERROR;
for(j = i; j<L.length-1; j++)
L.elem[j] == L.elem[j-1];
--L.length; //表长减 1
return OK;
}
由此可知,其时间复杂度为O(n)
3.设p为指向单循环链表上某结点的指针,则*p的直接前驱( C )
A.找不到 B.查找时间复杂度为O(1) C.查找时间复杂度为O( n ) D.查找结点的次数约为n
若此循环链表只有 三 个结点,则需将p->next进行 两 次循环找到p的直接前驱
四 个结点,则需将p->next进行 三 次循环找到p的直接前驱
N 个结点,则需将p->next进行 N-1 次循环找到p的直接前驱
所以其时间复杂度为 1+2+3+...+(n-1)=n(n-1)/2 , 即为O(n)
4.程序填空,已知线性表中的元素是无序的,并以带头结点的单向链表储存,试写一算法,删除表中所有大于min,小于max的元素,并完成以下程序填空
void delete(LinkList head, datatype min, datatype max)
{
LinkNode q,p;
q = head;
p = q->next;
while(p != NULL)
{
if(p->data <= min || p->data >= max)
{
q=p;
p = p->next;
}
else
{
//先空后实
q->next = p->next;
delete(p);
p = q->next;
}
}
}
5.设栈S和队列Q的初始状态为空,元素 e1、e2、e3、e4、e5、e6 依次通过栈S,一个元素出栈后即进入队列Q,若6个元素出队的顺序是e2、e4、e3、e6、e5、e1,则栈S的容量至少应该( C )
A. 6 B.4 C.3 D.2
答案是3
设栈长度为s,起始为0
因为栈后进先出,队列先进先出。
又因为元素E1.。E6是顺序入栈,那么分析过程如下:
按照出栈过程分析,因为给定出栈顺序:E2,E4,E3,E6,E5,E1,
E2要进栈,所以E1必须进栈,进栈顺序:E1,E2,所以s为2
下面E2出栈,打印出E2,剩余结果为E4,E3,E6,E5,E1,
因为E2出栈了,所以当前栈容量为2,但是只是用了1个,存放E1,下面继续
E3进栈,E4进栈,此时s为3,根据出栈结果,那么E4出栈,E3出栈,此时栈容量为3
但是只有E1在栈中,剩余结果为E6,E5,E1,
同理,E5进栈,E6进栈,此时栈被填满,容量为3,后E6出栈,E5出栈,E1出栈,栈空,容量为3.所以S的容量至少为3.
理解:
栈----先进后出
队列----先进先出
设栈的容量为x
1.x=0(舍去)
2.x=1(舍去) [ 此时栈中只有e1,而队列中先出的是e2,显然不符 ]
3.x=2 (舍去)
第一步:栈,此时只出e2,则队列先出e2
e2 e1
第二步:栈中只能进e3,所以队列中无法出e4【错误】
4.x=3(满足)
第一步:栈进入e1,e2 [ 结束后,e2进入队列]
e2 e1
第二步:栈进入e3,e4 [ 结束后e4,e3进入队列]
e4 e3 e1
第三步:栈进入e5,e6 [ 结束后e6,e5,e1进入队列]
e6 e5 e1
最终队列为
e1 e5 e6 e3 e4 e2
6.一个栈的入栈次序A,B,C,D,E,则栈不可能的输出序列是( C )
A.EDCBA B.DECBA C.DCEAB D.ABCDE
A:
栈的长度 大于等于 5
B:
栈的长度为 4
C:
改为DCEBA
D:
栈的长度为 1
【与5.为同类型题】
7.循环队列存储在数组A[M+1]中,则入队时的指针操作为( D )
A.rear=rear+1 B.rear=(rear+1)mod(M-1) C.rear=(rear+1)modM D.rear=(rear+1)mod(M+1)
循环队列:
需要少用一个元素空间来判断时 “空” 还是 “满”
队空条件:Q.front == Q.rear
队满条件:(Q.rear+1)% MAXSIZE == Q.front
8.若循环队列的容量为40(序号0-39),现经过一系列的进队出对运算后,front=11,rear=19,则循环队列中还有(8)个元素
此类题解法
Front指向循环队列起始位置的第一个
Rear指向循环队列最后一个元素的下一个
如果Rear小于Front,元素个数是50-Front+1+Rear-1 = 50-Front+Rear。
如果Rear大于Front,元素个数是Rear-Front
9. 求模式串“abaabcac”中next函数值序列(01122312),nextval函数值序列(01021302)
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
a | b | a | a | b | c | a | c | |
next | 0 | 1 | 1 | 2 | 2 | 3 | 1 | 2 |
nextval | 0 | 1 | 0 | 2 | 1 | 3 | 0 | 2 |
next算法:
第一位:恒为0
第二位:恒为1
第三位:看第二位,此题第二位为b,下标值为1,则与序号1的元素a进行比较
即b != a,序号一的下标值为0,结束,则第三位下标值为1
第四位:看第三位,此题第三位为a,下标值为1,则与序号1的元素a进行比较
即b = b,则第四位下标值为第三位下标值+1=2
第五位:看第四位,此题第四位为a,下标值为2,则与序号2的元素b进行比较
即a != b 且b的下标值=1(不为0),继续
此时将第四位的元素a与b的下标值1所对应的元素a进行比较
即a = a ,则第四位的下标值为第二位的下标值+1
同理即可
【前一位 相等+1 不相等继续比较对应下标】
nextval算法:
看此元素对应的next和顺序号
与对应下标元素进行比较,不等取后面的
相等取前面的
若前面的元素下标不为零,则继续
不等取后面的
相等取前面的
10.试设计一个算法,盘算一个带头结点的单链表是否递增
int increase(LinkList L){
p = L->next;
while(p->next !=NULL){
q = p->next
if( p->data < q->data )
p = q;
else
return 0; //不是单调递增
}
return 1; //是单调递增
}