第2章 线性表习题与解析

第2章 线性表习题与解析
第2章 线性表习题与解析

第二章线性表

2.1 基本概念

线性表的逻辑结构定义;线性表的两类基本存储结构及其相应的基本操作算法;单链表、循环链表、双向链表等链式线性表的特点;线性表的典型应用实例。要求学习者掌握:

(1)了解线性表的逻辑结构特性是数据元素之间存在着的线性关系,在计算机中表示这种关系的两类不同的存储结构是顺序存储结构和链式存储结构;

(2)熟练掌握线性表两类存储结构的描述方法,链表中的头结点、头指针和首元结点的区别及循环链表、双向链表的特点等;

(3)熟练掌握线性表在顺序存储结构上实现基本操作:查找、插入和删除的算法;

(4)熟练掌握在各种链表结构中实现线性表操作的基本方法,能在实际应用中选用适当的链表结构。了解静态链表,加深对链表本质的理解。

(5)能够从时间和空间复杂度的角度综合比较线性表两种存储结构的不同特点及其适用场合。

2.2 习题解析

一判断题(y/n)

1,顺序存储的线性表可以随机存取。

2,顺序存储的线性表的插入和删除操作不需要付出很大的代价,因为平均每次操作只有近一半的元素需要移动。

3,由于顺序存储要求连续的存储区域,所以在存储管理上不够灵活。

4,线性表中的元素可以是各种各样的但同一线性表中的数据元素具有相同的特性,因此是属于同一数据对象。

5,在线性表的顺序存储结构中,逻辑上相邻的两个元素但在物理位置上并不一定紧邻。

6,在线性表的链式存储结构中,逻辑上相邻的元素在物理位置上不一定相邻。

7,在单链表中,任何两个元素的存储位置之间都有固定的联系,因为可以从头结点进行查找任何一个元素。

8,线性表的链式存储结构优于顺序存储结构。

9,在线性表的顺序存储结构中,插入和删除时,移动元素的个数与该元素的位置有关。

10,线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素。

二单选题(请从下列A,B,C,D选项中选择一项)

1,线性表是:

一个有限序列,可以为空;

一个有限序列,不能为空;

一个无限序列,可以为空;

一个无序序列,不能为空。

2,对顺序存储的线性表,设其长度为n,在任何位置上插入或删除操作都是等概率的。插入一个元素时大约要移动表中的()个元素。

n/2

n+1/2

n-1/2

n

n+1

n-1

3,线性表采用链式存储时,其地址:

必须是连续的;

部分地址必须是连续的;

一定是不连续的;

连续与否均可以。

4, 设单链表中指针p指着结点M,指针f指着将要插入的新结点X,问:

X插在链表中两个数据元素M和N之间时,先修改()。

p↑.link:=f

p↑.link:=p↑.link↑.link

p↑.link:=f↑.link

f↑.link:=p↑.link

f↑.link:=NIL

f↑.link:=P

5,设单链表中指针p指着结点A,若要删除A之后的结点(若存在),则需修改指针的操作为()。p↑.link:=(p↑.link)↑.link

p:=p↑.link

p:=(p↑.link)↑.link

p↑.link:=p

6,在双向链表存储结构中删除p所指的结点时需修改指针( )。

(p↑.llink)↑.rlink:=p↑.rlink(p↑.rlink)↑.llink:=p↑.llink

p↑.llink:=(p↑.llink)↑.llink((p↑.llink)↑.llink)↑.rlink:=p

((p↑.llink)↑.llink)↑.rlink:=p p↑.llink:=(p↑.llink)↑.llink

7,在双向循环链表中,在p所指的结点之后插入指针f所指的结点,其操作是()。

p↑.rlink:=f;f↑.rlink:=p;(p↑.rlink)↑.llink:=f;f↑.rlink:=p↑.rlink

p↑.rlink:=f;(p↑.rlink)↑.llink:=f;f↑.llink:=p;f↑.rlink:=p↑.rlink

f↑.llink:=p;f↑.rlink:=p↑.rlink;p↑.rlink:=f;(p↑.rlink)↑.llink:=f

f↑.llink:=p;f↑.rlink:=p↑.rlink;(p↑.rlink)↑.llink:=f;p↑.rlink:=f

8,线性表的表元存储方式有()和链接两种。

循环链接

单向链接

双向链接

顺序链接

三编程题

1,写出将单链表倒置的算法

2,将两个有序表合并成一个有序表

3,设计候选人得票数的算法,并按得票多少为序输出统计结果

2.2.1 选择题

【1】链表不具有的特点是。

(A)可随机访问任一元素(B)插入删除不需要移动元素(C) 不必事先考虑存储空间(D) 所需空间与线性表长度成正比

【解析】本题考察对链表结构的基本特点的掌握。链表是一种线性表,它具有线性表的特点,所需空间与元素个数成正比。同时,它的每个元素由数据和指针两个域组成,因此,对元素的插入和删除操作只需修改指针即可。所以,(B)、(C)、(D)是正确的,而(A)不是链表的特点。

【2】如果一个链表中最常用的操作是在最后一个结点之后插入一个结点和删除最后一个结点,则采用存储方式最节省运算时间。

(A)单链表(B)双链表(C) 单循环链表(D) 带头结点的双循环链表

【解析】本题要求对链表中最后一个结点的操作(在其后插入元素和删除该元素)最方便,那么,在进行这些运算之前,首先需要搜索定位到最后一个结点。对于四种运算,假设链表长度为n

(1)单链表:要从表头结点开始搜索到倒数第二个结点(删除),或最后一个结点(插入),因此时间复杂度为O(n)。

(2)双链表:和单链表一样。

(3)单循环链表:虽然可以从表尾结点直接到达表头结点,但运算开始时也是要从表头结点开始搜索,因此时间复杂度为O(n)。

(4)带头结点的双循环链表:从头结点的前驱指针可以直接到达表尾结点,因此不耗费搜索时间。所以,本题答案为(D)。

【3】如果线性表最常用的操作是存取第I个元素及其前驱的值,则采用方式存储节省时间。

(A)单链表(B)双链表(C) 单循环链表(D) 顺序表

【解析】由于顺序表中对元素的存取可以直接根据编号(下标)。因此当指定存取元素的编号时,用顺序表作为链表的存储方式最节省时间。本题的正确答案是D。

【4】如果一个链表最常用的操作是在最后一个元素之后插入一个元素和删除最后一个元素,则采用方式存储最节省时间。

(A)单链表(B)双链表(C) 带头结点的双循环链表(D) 单循环链表

【解析】由于操作涉及寻找最后一个元素,对四种链表分析如下:

(1)单链表:从表中第一个结点开始到最后一个结点,时间耗费为O(n);

(2)双链表:和单链表一样;

(3)带头结点的双循环链表:可以直接从头结点沿前驱指针找到最后一个结点,因此时间耗费为O(1);

(4)单循环链表:也只能从第一个结点开始依次找到最后一个结点。

所以本题的答案是(C)。

【5】如果线性表的最常用的操作是存取指定序号的元素和在最后进行插入和删除运算,则采用存储方式最节省时间。

(A)顺序表(B)双链表(C)带头结点的双链表(D)单循环链表

【解析】根据顺序表的适合于随机存取以及不便于在表中进行插入和删除操作的特点,可以确定本题的正确选择是(A)。

【6】如果一个线性表最常用的操作是在最后一个元素后面插入一个元素和删除第一个元素,则采用存储方式最节省运算时间。

(A)单链表(B)双链表(C)只有头指针的单循环链表(D)只有尾指针的单循环链表

【解析】本题中的两种操作要求快速找到最后一个元素和第一个元素,不难想到,带有尾指针的单循环链表正好符合这两个要求。因此,本题的答案为(D)。

2.2.2 判断题

判断下列叙述是否正确,正确的打√,错误的打×。

【1】在顺序表中取出第i个元素所花费的时间与i成正比。

【解析】在顺序表中,元素的物理位置是由它们的编号决定的。因此,可根据编号(下标)来随机查找任一元素,查找所花费的时间与编号无关。本题答案为×。

【2】线性表的长度是指线性表所占用的存储空间的大小。

【解析】线性表长度的定义是它所包含的元素的个数。元素的类型决定了元素所占用存储空间的大小,但元素的个数不等价于元素的类型。因此本题答案为×。

【3】双循环链表中。任意一个结点的后继指针均指向其逻辑后继。

【解析】在双链表中,所有结点的后继指针指向的均为其逻辑后继。但对于双循环链表就有了一个特殊值——最后一个结点,它的后继指针指向的是链表中的第一个结点。因此,本题的答案为×。

【4】已知指针P指向链表L中的某个结点,则语句P=P->next不会删除该链表中的结点。【解析】语句P=P->next只会使指针后移一个元素,而不会删除元素,因此,本题的答案为√。

【5】链表只能借助于指针和动态变量来实现。

【解析】链表通常采用指针来实现地址的指向,但是,也可以利用数组模拟指针的方式来实现“静态链表”。因此本题的答案是×。

【6】设指针P指向单链表中的一个结点,则语句序列

U=P->next;

U=U->next;

将删除一个结点。

【解析】根据图2- ,我们可以看出,执行上面两条语句的结果只是把指针U向后移动了两个元素,而没有删除结点。因此,本题的答案是×。

图2-

【7】带头结点的单循环链表中,任一结点的后继指针均不空。

【解析】如图2- 是单循环链表的状态,可以看出,每个结点的后继指针均有所指。因此,本题的答案是√。

2.2.3 填空题

【1】在带有头结点H 的单链表中,第一个元素结点的指针是 。

【解析】带头结点的单链表中,第一个元素结点的指针存放在头结点H 的指针域中,如图2-1

因此答案为:H->next 。

【2】在双循环链表中,在指针P 所指结点前插入指针S 所指的结点,需执行下列语句: S->next=P; //①

S->prior=P.prior; //②

P->prior=S; // ③

=S;

图2-2

第四条语句该处理P 的前驱结点T 的后继next 指针的指向,因此应当是

P->prior->prior->next=S (注意:不能写成P->prior ->next=S !为什么?因为P-prior 已经发生了变化,原来是指向T ,而现在指向S )

或者 S->prior->next=S 。

【3】在单链表中,删除指针P 所指结点的后继结点的语句是 。

【解析】根据单链表的存储特点,即每个结点包括数据域和后继结点指针域两个部分,可以容易地写出语句:

P->next=P->next->next;

为本题答案。

【4】在双循环链表L 中,指针P 所指结点为尾结点的条件是 。

【解析】根据双循环链表的两个最重要的特点:

1) 所有结点都有前驱指针和后继指针;

2) 尾结点的后继指针指向第一个结点。

可以写出满足要求的语句

P->next=L;

【5】带头结点的双循环链表L 为空表的条件是 。

【解析】如图2- 所示,当带头结点的双循环链表的头结点L 的前驱和后继指针都志向自己时,链表为空。

图2-

写成语句是:

L->prior=L->next;

L->next=L ;

L->prior=L;

【6】在带头结点L 的双循环链表中,最后一个结点的指针是 。

图2-

头结点L 的前驱指针域中。因此,本题的答案是L->prior 。

【7】在只有尾指针R 的单循环链表中,在表尾插入一个结点S (S 为指向该结点的指针)的语句序列是

【解析】如图2- 所示,在只有尾指针的单循环链表中,在表尾插入S 指向的结点,

图2-

为了插入S 所指向的结点,要修改的指针有3

条,在上图中分别用数字标出。对应的语句是:

S->next=R->next;

R->next=S;

R=S;

【8】在单链表中,在指针P 所指结点的后面插入一个结点S 的语句序列是 。

【解析】如图2- 所示,在指针P 所指的结点后面插入一个结点S ,要修改两条指针,已经标出。

图2-

实现这两条指针的改动的语句是:

S->next=P->next;

P->next=S;

【9】在带有头结点的双链表L中,指针P所指结点是第一个元素的条件是。【解析】如图[6],第一个元素结点的最典型特征是它的前驱指针指向头结点。因此,本题应当填上

P->prior=L;

2.2.4 编程题

【1】设一个环上有若干个整数,采用单循环链表L存储该环,已知L的结点结构为

试画出链表L的结构图,并编写算法判断环上任意两个相邻元素值之差的绝对值是否不超过2。

【解析】画出链表L的结构图如图2-3所示。

图2-3

要求是:任何两个相邻元素之差的绝对值不大于2,注意不要漏掉了首尾两个元素之间的比较。一共需要比较n次(n为链表中元素的个数)。算法如下:

Step1:从L指向的第一个元素开始,用P指向该元素,把第一和第二个(P所指向结点的下一个结点)元素的差的绝对值与2比较,如果大于2,则转到Step ,否则进入Step2;Step2:P=P->next;

Step3:重复执行Step1和Step2的操作,直到P=L,即返回了链表的第一个结点。

Step4:输出“满足环上任意两个相邻元素值之差的绝对值是否不超过2”的信息,结束。Step5:输出“不满足环上任意两个相邻元素值之差的绝对值是否不超过2”的信息,结束。

下面写出C语言代码:

typedef struct linklist {

datatype data;

struct linklist *next;

};

int judge(linklist L) {

P=L;

Do {

If (abs(P->data-P->next->data)<=2)

P=P->next;

Else return (0);

}while(P!=L)

return (1);

}

思考:如果用while循环来控制,有没有上述方法方便?(提示:要进行两次P==L的

判断)

【2】已知单循环链表L至少有两个结点,每个结点的两个域为data(整型)和next,设计算法,判断链表中每个结点的data值是否小于其后续两个结点的data值之和。

【解析】本题的基本解法与上一题相同,唯一的主要区别是在设置循环条件时要考虑到当前结点(P)的后继结点和下一个后继结点,可以分别用

P->next

和 P->next->next

来表示。

类似要求的题目如:

已知带头结点的单循环链表L中至少有一个元素,判断L中各元素的值是否为其序号的X倍等等。

【3】设计算法将一个带有头结点的单循环链表A分解为两个具有相同结构的链表B和C,其中B表中结点为A中值为奇数的结点,而C表中结点为A中值为偶数的结点。要求不建立新的链表而使用原来的表A。

【解析】算法的基本思路是:从表A的第一个结点开始,对每个结点的值进行判断,是奇数就加入表B,是偶数就加入表C。操作分为两类:

1)对表中结点的值的判断;

2)向表尾添加结点。

由于题目要求不建立新链表,所以表B和C实质是在链表A上增加指针。

C语言程序如下:

void dissect(linklist A, linklist B, linklist C) {

New(C); //产生一个新的指针

RC=C; //RC作为指向表C的指针

P=A->next; //P指向表A中的第一个结点

Q=A; //Q为指向表B的指针

While(P!=A) { //循环结束条件是到达链表末尾

If(odd(P->data)) { //如果表A中当前结点为奇数

Q=P; //用Q来指向当前结点

P=P->next; //指针P后移

}

else { //如果表A中当前结点为偶数

Q->next=P->next; //Q跳过当前结点(不把当前结点加入表B)

RC->next=P; //当前结点加入表C

RC=P;

P=Q->next;

}

RC->next=C; //表C的尾结点的后继指针指向表C的头结点RC

B=A; //表B的头结点即是表A的头结点,因为运行程序后表A的链接决定了其表中结点的值都是奇数

}

【4】设计算法求两个带有头结点的递增单循环链表A、B的公共元素,并建成另一个单循环链表C。

【解析】

【5】已知递增有序的单链表A、B分别存储了一个集合。设计算法以求出两个集合A、B 的差集A-B(由只在A中出现而不在B中出现的元素组成),同时返回元素的个数。

【解析】

【6】两个单链表A和B的结构相同,都包括一个数据域和一个指针域,设计算法,判断A 是否为B的子集,即判断A中的元素是否都包含在B中。

2.11 设顺序表va中的数据元素递增有序。试写一算法,将x插入到顺序表的适当位置上,以保持该表的有序性。

Status OrderListInsert-sq(SqList va, ElemType x) {

//将x插入到递增有序的顺序表va中,插入后va仍然递增有序(算法1)

if (va.length==va.listsize){

newbase=(ElemType *)realloc(va.elem,(va.listsize+LISTINCREMENT)*sizeof(ElemType));

if (!newbase) exit(OVERFLOW);

va.elem=newbase;

va.listsize+=LISTINCREMENT;

}//当前存储空间已满,增加分配空间

if (!va.length) {va.elem[0]=x; ++va.length; return OK;}

q=&(va.elem[0]);

while (*q<=x)&&(q<=&(va.elem[va.length-1])) ++q; //查找插入位置

for (p=&(va.elem[va.length-1]); p>=q; --p) *(p+1)=*p;

*q=x;

++va.length;

return OK;

}//OrderListInsert-sq

Status OrderListInsert-sq(SqList va, ElemType x) {

//将x插入到递增有序的顺序表va中,插入后va仍然递增有序(算法2)

if (va.length==va.listsize){

newbase=(ElemType *)realloc(va.elem,(va.listsize+LISTINCREMENT)*sizeof(ElemType));

if (!newbase) exit(OVERFLOW);

va.elem=newbase;

va.listsize+=LISTINCREMENT;

}//当前存储空间已满,增加分配空间

if (!va.length) {va.elem[0]=x; ++va.length; return OK;}

p=&(va.elem[va.length-1]);

while (P>=&(va.elem[0])&&*p>x) {*(p+1)=*p; --p;}

*(p+1)=x;

++va.length;

return OK;

}//OrderListInsert-sq

2.12 设A=(a1,...,am)和B=(b1,...,bn)均为顺序表,A'和B'分别为A和B中除去最大共同前缀后的子表。若A'=B'=空表,则A=B;若A'=空表,而B'≠空表,或者两者均不为空表,且A'的首元小于B'的首元,则AB。试写一个比较A,B大小的算法。

int Compare-List(SqList a, SqList b){

//a,b为顺序表,若ab时,返回1

i=0;

while (i<=a.length-1) && (i<=b.length-1) && (a.elem[i]=b.elem[i]) ++i;

switch {

case i=a.length && i=b.length : return 0; break;

case (i=a.length && i<=b.length-1)

||(i<=a.length-1 && i<=b.length-1 && a.elem[i]

default : return 1;

}

}//Compare-List

2.19

status del-l(LinkList &la, int mink, int maxk){

//la为带头结点的单链表的头指针,单链表中的结点以值递增有序排列

//本算法删除表中所有值大于mink且小于maxk的元素,mink

if (mink>=maxk) return ERROR

p=la;

while (p->next<>NULL && p->next->data<=mink) p=p->next;

q=p;

while (q->next<>NULL && q->next->datanext ;

q=q->next;

p1=p->next;

while (p1<>q) {q1=p1; p1=p1->next; free(q1);}

p->next=q;

}//del-l

2.21

LinkList priou(LinkList la, LinkList q1){

//返回指向单链表la中结点的指针p1,p1->next=q1

p1=la;

while (p1->next!=q1) p1=p1->next;

return p1;

}//priou

void Reverse-List-l(LinkList &la) {

//就地逆置单链表la(算法1)

if (!la->next) return;

p=la->next; q=priou(la, NULL);

while (p!=q) {

p->data〈-〉q->data;

if (p=q) return;

q=priou(la, q);

}

}//Reverse-List-l

void Reverse-List-l(LinkList &la) { //就地逆置单链表la(算法2)p=priou(la, NULL); last=p;

pre=priou(la,p);

while (pre!=la) {

p->next=pre;

p=pre;

pre=priou(la,p);

}

p->next=NULL;

la->next=last;

}//Reverse-List-l

void Reverse-List-l(LinkList &la) { //就地逆置单链表la(算法3)if (!la->next) return;

pre=la->next;

if (!pre->next) return;

p=pre->next; pre->next=NULL; next=p->next;

while (p) {

p->next=pre;

pre=p;

p=next;

if (p) next=p->next;

}

la->next=pre;

return;

}//Reverse-List-l

void Reverse-List-l(LinkList &la) { //就地逆置单链表la(算法4)p=la->next;

if (!p || !p->next) return;

pn=p->next; p->next=NULL; while (pn) {

p=pn; pn=pn->next;

p->next=la->next; la->next=p;

}

return;

}//Reverse-List-l

2.24

void MergeList(LinkList &a, LinkList &b, LinkList &c) {

//已知单链表a和b的元素按值递增有序排列

//归并a和b得到新的单链表c,c的元素按值递减有序

c=a; p=a->next; q=b->next; c->next=NULL;

while (p && q)

if (p->datadata) {

pn=p->next; p->next=c->next;

c->next=p; p=pn;

}

else {

qn=q->next; q->next=c->next;

c->next=q; q=qn;

}

while (p) {pn=p->next; p->next=c->next; c->next=p; p=pn;}

while (q) {qn=q->next; q->next=c->next; c->next=q; q=qn;}

free(b);

}//MergeList

2.33

void CutApart-LinkList(LinkList &l, LinkList la, LinkList lb, LinkList lc){

//单链表l中的元素含有三类字符:字母、数字和其它字符

//本算法将l分割为la、lb和lc三个循环链表,它们分别只含字母、数字和其它字符la=(LinkList)malloc(sizeof(LNode)); la->next=la;

lb=(LinkList)malloc(sizeof(LNode)); lb->next=lb;

lc=(LinkList)malloc(sizeof(LNode)); lc->next=lc;

pn=l->next;

while (pn){

p=pn; pn=pn->next;

switch {

case ('a'<=p->data && p->data<='z')

||('A'<=p->data && p->data<='Z') : p->next=la->next; la->next=p; break;

case ('0'<=p->data && p->data<='9') : p->next=lb->next; lb->next=p; break;

default : p->next=lc->next; lc->next=p;

}//switch

}//while

free(l);

}//CutApart-LinkList

2.39

typedef struct {

float coef;

int expn;

}*Poly, ElemType;

float Polynomial(Poly &p, int m, float x0){

//多项式p的顺序存储结构中依次存放有c1,e1,c2,e2,...,cm,em

//x0为给定值,本算法计算pn(x0)的值

x=x0^p[0].expn;

pn=p[0].coef*x;

for (i=1; i<=m; ++i){

x=x*x0^(p[i].expn-p[i-1].expn);

pn=pn+p[i].coef*x;

}

retrun pn;

}//Polynomial

(以下内容来自https://www.360docs.net/doc/7311609608.html,)

第二章线性表

2.10

Status DeleteK(SqList &a,int i,int k)//删除线性表a中第i个元素起的k个元素

{

if(i<1||k<0||i+k-1>a.length) return INFEASIBLE;

for(count=1;i+count-1<=a.length-k;count++) //注意循环结束的条件

a.elem[i+count-1]=a.elem[i+count+k-1];

a.length-=k;

return OK;

}//DeleteK

2.11

Status Insert_SqList(SqList &va,int x)//把x插入递增有序表va中

{

if(va.length+1>va.listsize) return ERROR;

va.length++;

for(i=va.length-1;va.elem[i]>x&&i>=0;i--)

va.elem[i+1]=va.elem[i];

va.elem[i+1]=x;

return OK;

}//Insert_SqList

2.12

int ListComp(SqList A,SqList B)//比较字符表A和B,并用返回值表示结果,值为正,表示A>B;值为负,表示A

{

for(i=1;A.elem[i]||B.elem[i];i++)

if(A.elem[i]!=B.elem[i]) return A.elem[i]-B.elem[i];

}//ListComp

2.13

LNode* Locate(LinkList L,int x)//链表上的元素查找,返回指针

{

for(p=l->next;p&&p->data!=x;p=p->next);

return p;

}//Locate

2.14

int Length(LinkList L)//求链表的长度

{

for(k=0,p=L;p->next;p=p->next,k++);

return k;

}//Length

2.15

void ListConcat(LinkList ha,LinkList hb,LinkList &hc)//把链表hb接在ha后面形成链表hc {

hc=ha;p=ha;

while(p->next) p=p->next;

p->next=hb;

}//ListConcat

2.16

见书后答案.

2.17

Status Insert(LinkList &L,int i,int b)//在无头结点链表L的第i个元素之前插入元素b {

p=L;q=(LinkList*)malloc(sizeof(LNode));

q.data=b;

if(i==1)

{

q.next=p;L=q; //插入在链表头部

}

else

{

while(--i>1) p=p->next;

q->next=p->next;p->next=q; //插入在第i个元素的位置

}

}//Insert

2.18

Status Delete(LinkList &L,int i)//在无头结点链表L中删除第i个元素

{

if(i==1) L=L->next; //删除第一个元素

else

{

while(--i>1) p=p->next;

p->next=p->next->next; //删除第i个元素

}

}//Delete

2.19

Status Delete_Between(Linklist &L,int mink,int maxk)//删除元素递增排列的链表L中值大于mink且小于maxk的所有元素

{

p=L;

while(p->next->data<=mink) p=p->next; //p是最后一个不大于mink的元素

if(p->next) //如果还有比mink更大的元素

{

q=p->next;

while(q->datanext; //q是第一个不小于maxk的元素

p->next=q;

}

}//Delete_Between

2.20

Status Delete_Equal(Linklist &L)//删除元素递增排列的链表L中所有值相同的元素

{

p=L->next;q=p->next; //p,q指向相邻两元素

while(p->next)

{

if(p->data!=q->data)

{

p=p->next;q=p->next; //当相邻两元素不相等时,p,q都向后推一步

}

else

{

while(q->data==p->data) q=q->next;

p->next=q;p=q;q=p->next; //当相邻元素相等时删除多余元素

}

}//while

}//Delete_Equal

2.21

void reverse(SqList &A)//顺序表的就地逆置

{

for(i=1,j=A.length;i

A.elem[i]<->A.elem[j];

}//reverse

2.22

void LinkList_reverse(Linklist &L)//链表的就地逆置;为简化算法,假设表长大于2

{

p=L->next;q=p->next;s=q->next;p->next=NULL;

while(s->next)

{

q->next=p;p=q;

q=s;s=s->next; //把L的元素逐个插入新表表头

}

q->next=p;s->next=q;A->next=s;

}//LinkList_reverse

分析:本算法的思想是,逐个地把L的当前元素q插入新的链表头部,p为新表表头.

2.23

void merge1(LinkList &A,LinkList &B,LinkList &C)//把链表A和B合并为C,A和B的元素间隔排列,且使用原存储空间

{

p=A->next;q=B->next;C=A;

while(p&&q)

{

s=p->next;p->next=q; //将B的元素插入

if(s)

{

t=q->next;q->next=s; //如A非空,将A的元素插入

}

p=s;q=t;

}//while

}//merge1

2.24

void reverse_merge(LinkList &A,LinkList &B,LinkList &C)//把元素递增排列的链表A和B合并为C,且C中元素递减排列,使用原空间

{

pa=A->next;pb=B->next;pre=NULL; //pa和pb分别指向A,B的当前元素

while(pa&&pb)

{

if(pa->datadata)

{

pc=pa;q=pa->next;pa->next=pre;pa=q; //将A的元素插入新表

}

else

{

pc=pb;q=pb->next;pb->next=pre;pb=q; //将B的元素插入新表

}

pre=pc;

}

while(pa)

{

q=pa->next;pa->next=pc;pc=pa;pa=q; //插入A中余下的元素

while(pb)

{

q=pb->next;pb->next=pc;pc=pb;pb=q; //插入B中余下的元素

}

C=A;A->next=pc; //构造新表头

}//reverse_merge

分析:本算法的思想是,按从小到大的顺序依次把A和B的元素插入新表的头部pc处,最后处理A或B的剩余元素.

2.25

void SqList_Intersect(SqList A,SqList B,SqList &C)//求元素递增排列的线性表A和B的元素的交集并存入C中

{

i=1;j=1;k=0;

while(A.elem[i]&&B.elem[j])

{

if(A.elem[i]

if(A.elem[i]>B.elem[j]) j++;

if(A.elem[i]==B.elem[j])

{

C.elem[++k]=A.elem[i]; //当发现了一个在A,B中都存在的元素,

i++;j++; //就添加到C中

}

}//while

}//SqList_Intersect

2.26

void LinkList_Intersect(LinkList A,LinkList B,LinkList &C)//在链表结构上重做上题

{

p=A->next;q=B->next;

pc=(LNode*)malloc(sizeof(LNode));

while(p&&q)

{

if(p->datadata) p=p->next;

else if(p->data>q->data) q=q->next;

else

{

s=(LNode*)malloc(sizeof(LNode));

s->data=p->data;

pc->next=s;pc=s;

p=p->next;q=q->next;

}

}//while

C=pc;

}//LinkList_Intersect

void SqList_Intersect_True(SqList &A,SqList B)//求元素递增排列的线性表A和B的元素的交集并存回A中

{

i=1;j=1;k=0;

while(A.elem[i]&&B.elem[j])

{

if(A.elem[i]

else if(A.elem[i]>B.elem[j]) j++;

else if(A.elem[i]!=A.elem[k])

{

A.elem[++k]=A.elem[i]; //当发现了一个在A,B中都存在的元素

i++;j++; //且C中没有,就添加到C中

}

}//while

while(A.elem[k]) A.elem[k++]=0;

}//SqList_Intersect_True

2.28

void LinkList_Intersect_True(LinkList &A,LinkList B)//在链表结构上重做上题

{

p=A->next;q=B->next;pc=A;

while(p&&q)

{

if(p->datadata) p=p->next;

else if(p->data>q->data) q=q->next;

else if(p->data!=pc->data)

{

pc=pc->next;

pc->data=p->data;

p=p->next;q=q->next;

}

}//while

}//LinkList_Intersect_True

2.29

void SqList_Intersect_delete(SqList &A,SqList B,SqList C)//从有序顺序表A中删除那些在B和C中都出现的元素

{

i=1;j=1;k=1;

while(B.elem[i]&&C.elem[j])

{

if(B.elem[i]

else if(B.elem[i]>C.elem[j]) j++;

else //找到了需要从A中删除的元素

{

u=B.elem[i];

while(A.elem[k]

for(;A.elem[k]==u;k++)

A.elem[k]=INFINITY; //把A中待删除元素置换为特殊记号

while(B.elem[i]==u) i++;

while(C.elem[j]==u) j++;

}//else

}//while

for(i=1,j=1;j<=A.length;i++) //第二遍扫描A,删除特殊记号

{

while(A.elem[j]==INFINITY)

{

j++;A.length--;

}

if(i

j++;

}//for

}//SqList_Intersect_delete

分析:本算法的时间复杂度为O(m),m为表长.思考:你自己的算法时间复杂度是多少?实际上也可以只用一遍扫描就完成整个操作,且时间复杂度也为O(m),但非常复杂,你能写出来吗?

2.30

void LinkList_Intersect_delete(LinkList &A,LinkList B,LinkList C)//在链表结构上重做上题{

p=B->next;q=C->next;r=A-next;

while(p&&q&&r)

{

if(p->datadata) p=p->next;

else if(p->data>q->data) q=q->next;

else

{

u=p->data; //确定待删除元素u

while(r->next->datanext; //确定最后一个小于u的元素指针r

if(r->next->data==u)

{

s=r->next;

while(s->data==u)

{

t=s;s=s->next;free(t); //确定第一个大于u的元素指针s

}//while

r->next=s; //删除r和s之间的元素

}//if

while(p->data=u) p=p->next;

while(q->data=u) q=q->next;

}//else

}//while

}//LinkList_Intersect_delete

2.31

Status Delete_Pre(CiLNode *s)//删除单循环链表中结点s的直接前驱

{

p=s;

while(p->next->next!=s) p=p->next; //找到s的前驱的前驱p

p->next=s;

return OK;

}//Delete_pre

2.32

Status DuLNode_pre(DuLinkList &L)//完成双向循环链表结点的pre域

{

for(p=L;!p->next->pre;p=p->next) p->next->pre=p;

return OK;

}//DuLNode_pre

2.33

Status LinkList_divide(LinkList &L,CiList &A,CiList &B,CiList &C)//把单链表L的元素按类型分为三个循环链表.CiList为带头结点的单循环链表类型.

{

s=L->next;

A=(CiList*)malloc(sizeof(CiLNode));p=A;

B=(CiList*)malloc(sizeof(CiLNode));q=B;

C=(CiList*)malloc(sizeof(CiLNode));r=C; //建立头结点

while(s)

{

if(isalphabet(s->data))

{

p->next=s;p=s;

}

else if(isdigit(s->data))

{

q->next=s;q=s;

}

else

{

r->next=s;r=s;

}

}//while

p->next=A;q->next=B;r->next=C; //完成循环链表

}//LinkList_divide

2.34

void Print_XorLinkedList(XorLinkedList L)//从左向右输出异或链表的元素值

{

第二章线性表答案

2.11 设顺序表va中的数据元素递增有序。试写一算法,将x插入到顺序表的适当位置上,以保持该表的有序性。 Status OrderListInsert-sq(SqList va, ElemType x) { //将x插入到递增有序的顺序表va中,插入后va仍然递增有序(算法1) if (va.length==va.listsize){ newbase=(ElemType *)realloc(va.elem,(va.listsize+LISTINCREMENT)*sizeof(ElemType)); if (!newbase) exit(OVERFLOW); va.elem=newbase; va.listsize+=LISTINCREMENT; }//当前存储空间已满,增加分配空间 if (!va.length) {va.elem[0]=x; ++va.length; return OK;} q=&(va.elem[0]); while (*q<=x)&&(q<=&(va.elem[va.length-1])) ++q; //查找插入位置 for (p=&(va.elem[va.length-1]); p>=q; --p) *(p+1)=*p; *q=x; ++va.length; return OK; }//OrderListInsert-sq Status OrderListInsert-sq(SqList va, ElemType x) { //将x插入到递增有序的顺序表va中,插入后va仍然递增有序(算法2) if (va.length==va.listsize){ newbase=(ElemType *)realloc(va.elem,(va.listsize+LISTINCREMENT)*sizeof(ElemType)); if (!newbase) exit(OVERFLOW); va.elem=newbase; va.listsize+=LISTINCREMENT; }//当前存储空间已满,增加分配空间 if (!va.length) {va.elem[0]=x; ++va.length; return OK;} p=&(va.elem[va.length-1]); while (P>=&(va.elem[0])&&*p>x) {*(p+1)=*p; --p;} *(p+1)=x; ++va.length;

线性代数第二章答案

第二章 矩阵及其运算 1 已知线性变换 ?????++=++=++=3 213321232113235322y y y x y y y x y y y x 求从变量x 1 x 2 x 3到变量y 1 y 2 y 3的线性变换 解 由已知 ? ??? ?????? ? ?=???? ??221321323513122y y y x x x 故 ???? ?????? ? ?=???? ??-3211 221323513122x x x y y y ? ??? ?????? ??----=321423736 947y y y ?????-+=-+=+--=3 21332123 211423736947x x x y x x x y x x x y 2 已知两个线性变换 ?????++=++-=+=321332123 11542322y y y x y y y x y y x ?????+-=+=+-=3 233122 11323z z y z z y z z y 求从z 1 z 2 z 3到x 1 x 2 x 3的线性变换 解 由已知 ???? ?????? ? ?-=???? ??221321514232102y y y x x x ??? ? ?????? ??--???? ??-=32131 010 2013514232102z z z ??? ? ?????? ??----=321161109412316z z z

所以有?????+--=+-=++-=3 21332123 2111610941236z z z x z z z x z z z x 3 设???? ??--=111111111A ??? ? ??--=150421321B 求3AB 2A 及A T B 解 ??? ? ??---???? ??--???? ??--=-1111111112150421321111111111323A AB ???? ??----=???? ??---???? ??-=2294201722213211111111120926508503 ??? ? ??-=???? ??--???? ??--=092650850150421321111111111B A T 4 计算下列乘积 (1)??? ? ?????? ??-127075321134 解 ???? ?????? ??-127075321134???? ???+?+??+?-+??+?+?=102775132)2(71112374??? ? ??=49635 (2)???? ??123)321( 解 ??? ? ??123)321((132231)(10)

线性代数第二章矩阵试题及答案

第二章矩阵 一、知识点复习 1、矩阵的定义 由m?n个数排列成的一个m行n列的表格,两边界以圆括号或方括号,就成为一个m?n型矩阵。例如 2 -1 0 1 1 1 1 1 0 2 2 5 4 -2 9 3 3 3 -1 8 是一个4?5矩阵. 一个矩阵中的数称为它的元素,位于第i行第j列的数称为(i,j)位元素。 元素全为0的矩阵称为零矩阵,通常就记作0。 两个矩阵A和B相等(记作A=B),是指它的行数相等,列数也相等(即它们的类型相同),并且对应的元素都相等。 2、n阶矩阵与几个特殊矩阵 行数和列数相等的矩阵称为方阵,行列数都为n的矩阵也常常叫做n阶矩阵。 n阶矩阵的从左上角到右下角的对角线称为主对角线。 下面列出几类常用的n阶矩阵,它们都是考试大纲中要求掌握的. 对角矩阵: 对角线外的的元素都为0的n阶矩阵. 单位矩阵: 对角线上的的元素都为1的对角矩阵,记作E(或I). 数量矩阵: 对角线上的的元素都等于一个常数c的对角矩阵,它就是c E. 上三角矩阵: 对角线下的的元素都为0的n阶矩阵. 下三角矩阵: 对角线上的的元素都为0的n阶矩阵. 对称矩阵: 满足A T=A矩阵,也就是对任何i,j,(i,j)位的元素和(j,i)位的元素总是相等的n阶矩阵. 反对称矩阵:满足A T=-A矩阵.也就是对任何i,j,(i,j)位的元素和(j ,i)位的元素之和总等于0的n阶矩阵.反对称矩阵对角线上的元素一定都是0.) 正交矩阵:若AA T=A T A=E,则称矩阵A是正交矩阵。 (1)A是正交矩阵?A T=A-1 (2)A是正交矩阵?2A=1 阶梯形矩阵:一个矩阵称为阶梯形矩阵,如果满足: ①如果它有零行,则都出现在下面。 ②如果它有非零行,则每个非零行的第一个非0元素所在的列号自上而下严格单调递增。 把阶梯形矩阵的每个非零行的第一个非0元素所在的位置称为台角。 每个矩阵都可以用初等行变换化为阶梯形矩阵,这种运算是在线性代数的各类计算题中频繁运用的基本运算,必须十分熟练。 请注意:一个矩阵用初等行变换化得的阶梯形矩阵并不是唯一的,但是其非零行数和台角位置是确定的。 3、矩阵的线形运算 (1)加(减)法:两个m?n的矩阵A和B可以相加(减),得到的和(差)仍是m?n矩阵,记作A+B (A-B),运算法则为对应元素相加(减). (2)数乘: 一个m?n的矩阵A与一个数c可以相乘,乘积仍为m?n的矩阵,记作c A,运算法则为A的每个元素乘c. 这两种运算统称为线性运算,它们满足以下规律: ①加法交换律:A+B=B+A. 2加法结合律:(A+B)+C=A+(B+C). ③加乘分配律:c(A+B)=c A+c B.(c+d)A=c A+d A. ④数乘结合律: c(d)A=(cd)A. ⑤ c A=0? c=0 或A=0. 4、矩阵乘法的定义和性质 (1)当矩阵A的列数和B的行数相等时,则A和B可以相乘,乘积记作AB. AB的行数和A相等,列数和B相等. AB的(i,j)位元素等于A的第i个行向量和B的第j个列向量(维数相同)对应分量乘积之和.

第二章线性表答案

第2章线性表 一选择题 1.下述哪一条是顺序存储结构的优点?( A ) A.存储密度大 B.插入运算方便 C.删除运算方 便 D.可方便地用于各种逻辑结构的存储表示 2.下面关于线性表的叙述中,错误的是哪一个?( B )A.线性表采用顺序存储,必须占用一片连续的存储单元。B.线性表采用顺序存储,便于进行插入和删除操作。 C.线性表采用链接存储,不必占用一片连续的存储单元。D.线性表采用链接存储,便于插入和删除操作。 3.线性表是具有n个( C )的有限序列(n>0)。 A.表元素 B.字符 C.数据元 素 D.数据项 E.信息项 4.若某线性表最常用的操作是存取任一指定序号的元素和在最后进行插入和删除运算,则利用( A )存储方式最节省时间。 AHA12GAGGAGAGGAFFFFAFAF

A.顺序表 B.双链表 C.带头结点的双循环链表 D.单循环链表 5.某线性表中最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素,则采用( D )存储方式最节省运算时间。 A.单链表 B.仅有头指针的单循环链 表 C.双链表D.仅有尾指针的单循环链表 6.设一个链表最常用的操作是在末尾插入结点和删除尾结点,则选用( D )最节省时间。 A. 单链表 B.单循环链表 C. 带尾指针的单循环链表 D.带头结点的双循环链表 7.若某表最常用的操作是在最后一个结点之后插入一个结点或删除最后一个结点。则采用( D )存储方式最节省运算时间。 AHA12GAGGAGAGGAFFFFAFAF

A.单链表 B.双链表 C.单循环链 表 D.带头结点的双循环链表 8. 静态链表中指针表示的是( BC ). A.内存地址 B.数组下标 C.下一元素地址D.左、右孩子地址 9. 链表不具有的特点是( C ) A.插入、删除不需要移动元素 B.可随机访问任一元素C.不必事先估计存储空间 D.所需空间与线性长度成正比 10. 下面的叙述不正确的是( BC ) A.线性表在链式存储时,查找第i个元素的时间同i的值成正比 AHA12GAGGAGAGGAFFFFAFAF

数据结构第二章线性表测试题

第二章线性表 1、描述一下三个概念的区别:头指针,头结点,首元结点。并给予图示。 2、对于有头结点的单链表,分别写出定位成功时,实现下列定位语句序列。(1)定位到第i 个结点a i ; (2)定位到第i 个结点的前驱a i-1; (3)定位到尾结点; (4)定位到尾结点的前驱。 3、已知L 是有表头结点的单链表,且P 结点既不是首元结点,也不是尾结点,试写出实现下列功能的语句序列。 (1)在P 结点后插入S 结点;(2)在P 结点前插入S 结点;(3)在表首插入S 结点;(4)在表尾插入S 结点 . p=head; p=head; j=0; while ( p && jnext; j++;} p=head; j=0; while ( p && jnext; j++;} p=head; while ( p ->next ) p=p->next; while ( p->next->next ) p=p->next; (1)s->next=p->next; p->next=s; (2)q =L ; whil e ( q ->next !=p ) q =q ->next;s->next=p 或 q ->next ; q ->next=s; (3 ) s->next=L ->next; L ->next=s; (4)q =L ; whil e ( q ->next !=NULL) q =q ->next;s->next= q ->next ; q ->next=s;

4、设计算法:在顺序表中删除值为e 的元素,删除成功,返回1;否则,返回0。 5、设计一个算法,将一个带头节点的数据域依次为a 1,a 2,…,a n (n ≥3)的单链表的所有节点逆置,即第一个节点的数据域变为a n ,…,最后一个节点的数据域为a 1。(注意:先用自然语言描述算法基本思想,然后用类C++语言描述) int Sqlist::DeleteElem( T e ) { for (i=1; i<=len g t h ; i ++) // 按值顺序查找 * i 可从0开始 if (elem[i-1]= =e) // 找到,进行删除操作 { for ( j=i; jnext; 4 LinkList* pri = NULL; //之前的节点 5 while(p){ 6 LinkList* q = new LinkList; 7 q->data = p->data; //把当前节点记录下来 8 q->next = pri; 9 pri = q; 10 head->next = q; 11 LinkList* t = p; //当前节点没用了删除掉 12 p=p->next; 13 delete(t); 14 } 15 }

第2章线性表习题解答

第2章线性表习题解答

第2章习题 (2) 第2章习题 2.1若将顺序表中记录其长度的分量listlen改为指向最后一个元素的位置last,在实现各基本运算时需要做那些修改? 【解】 //用线性表最后一个元素的下标last代替listLen实现顺序表 #define MAXLEN 100 typedef int elementType; typedef struct sllLast { elementType data[MAXLEN]; int last; }seqList; //初始化 void initialList(seqList &S)

{ https://www.360docs.net/doc/7311609608.html,st=-1; } //求表长度 int listLength(seqList S) { return https://www.360docs.net/doc/7311609608.html,st+1; } //按序号取元素 bool getElement(seqList S,int i,elementType &x) { if(i<1 || i>https://www.360docs.net/doc/7311609608.html,st+1) //i为元素编号,有效范围在https://www.360docs.net/doc/7311609608.html,st+1之间 return false; else { x=S.data[i-1];

return true; } } //查找元素x,成功:返回元素编号;失败:返回0 int listLocate(seqList S,elementType x) { int i; for(i=0;i<=https://www.360docs.net/doc/7311609608.html,st;i++) { if(S.data[i]==x) return i+1; //找到,转换为元素编号输出 } return 0; } //插入元素 int listInsert(seqList &S,elementType x, int i)

第二章线性表测试题

第二章测试试题 班级:学号:姓名:成绩: 一、选择题(每小题5分) 1.线性表是( A )。 A一个有限序列,可以为空;B一个有限序列,不能为空; C一个无限序列,可以为空;D一个无序序列,不能为空。 2.用链表表示线性表的优点是(C)。 A便于随机存取 B花费的存储空间较顺序存储少 C便于插入和删除 D数据元素的物理顺序与逻辑顺序相同 3.某链表中最常用的操作是在最后一个元素之后插入一个元素和删除最后一个元素,则采用( D )存储方式最节省运算时间。 A单链表 B双链表 C单循环链表 D带头结点的双循环链表 4.带头结点的单链表head为空的判定条件是(B )。 A.head==NULL; B.head->next==NULL; C.head->next==head; D.head!=NULL; 5.在一个单链表中,已知q所指结点是p所指结点的前驱结点,若在q和p之间插入s结点,则执行(C )。 A.s->next=p->next;p->next=s; B.p->next=s->next;s->next=p; C.q->next=s;s->next=p; D.p->next=s; s->next=q; 二、填空题(每小题5分) 1.给定有n个结点的向量,建立一个单链表的时间复杂度_______。建立一个有序单链表的时间复杂度_______。 2.从一个具有n个结点的单链表中查找其值等于x结点时,在查找成功的情况下,需平均比较_____个结点。 3.在一个长度为n的线性表(采用顺序存储结构)中删除第i个元素(1≤i≤n)时,需向前移动____个元素。 4.当对一个线性表经常进行存取操作,而很少进行插入和删除操作时,则采用_____存储结构为宜。相反,当经常进行的是插入和删除操作时,则采用_______存储结构为宜。5.对顺序存储的线性表,设其长度为n,在任何位置上插入或删除操作都是等概率的。插入一个元素时平均要移动表中的个元素。 三、算法设计题(每小题25分) 1.设有一个用向量表示的线性表L,要求写出一个将该表逆置的过程,允许在原表的存储空间外再增加一个附加的工作单元。 2.已知两个整数集合A和B,它们的元素分别依元素值递增有序存放在两个单链表HA 和HB中,编写一个函数求出这两个集合的并集C,并要求集合C的链表的结点仍依元素值递增有序存放。(注意:并集不是归并)

线性代数课后习题答案(陈维新)

第一章 行列式 习题1.1 1. 证明:(1)首先证明)3(Q 是数域。 因为)3(Q Q ?,所以)3(Q 中至少含有两个复数。 任给两个复数)3(3,32211Q b a b a ∈++,我们有 3 )()3()3)(3(3)()()3()3(3)()()3()3(2121212122112121221121212211b a a b b b a a b a b a b b a a b a b a b b a a b a b a +++=++-+-=+-++++=+++。 因为Q 是数域,所以有理数的和、差、积仍然为有理数,所以 ) 3(3)()3()3)(3()3(3)()()3()3()3(3)()()3()3(2121212122112121221121212211Q b a a b b b a a b a b a Q b b a a b a b a Q b b a a b a b a ∈+++=++∈-+-=+-+∈+++=+++。 如果0322≠+b a ,则必有22,b a 不同时为零,从而0322≠-b a 。 又因为有理数的和、差、积、商仍为有理数,所以 )3(33) (3)3() 3)(3()3)(3(3 32 2 22212122222121222222112211Q b a b a a b b a b b a a b a b a b a b a b a b a ∈--+--= -+-+= ++。 综上所述,我们有)3(Q 是数域。 (2)类似可证明)(p Q 是数域,这儿p 是一个素数。 (3)下面证明:若q p ,为互异素数,则)()(q Q p Q ?。 (反证法)如果)()(q Q p Q ?,则q b a p Q b a +=? ∈?,,从而有 q ab qb a p p 2)()(222++==。 由于上式左端是有理数,而q 是无理数,所以必有02=q ab 。 所以有0=a 或0=b 。 如果0=a ,则2 qb p =,这与q p ,是互异素数矛盾。 如果0=b ,则有 a p =,从而有“有理数=无理数”成立,此为矛盾。 所以假设不成立,从而有)()(q Q p Q ?。

(完整版)数据结构第二章线性表1答案

(A )需经常修改L 中的结点值 (E )需不断对L 进行删除插入 第二部分线性表 、选择题 1 ?关于顺序存储的叙述中,哪一条是不正确的 (B ) A. 存储密度大 B. 逻辑上相邻的结点物理上不必邻接 C. 可以通过计算直接确定第 i 个结点的位置 D. 插入、删除操作不方便 2.长度为n 的单链表连接在长度为 m 的单链表后的算法的时间复杂度为 (C ) A 0( n ) B 0(1) C 0(m ) D 0(m+n ) 3 .在n 个结点的顺序表中,算法的时间复杂度是 0(1)的操作是:(A ) A 访问第i 个结点(1<=i<=n )和求第i 个结点的直接前趋(2<=i<=n ) B 在第i 个结点(1<=i<=n )后插入一个新结点 C 删除第i 个结点(1<=i<=n ) D 将n 个结点从小到大排序 4.一个向量第一个兀素的存储地址是 100 ,每个兀素的长度为 2 ,则第5 个兀素的地址是 (B ) ( A ) 110 ( B ) 108 (C ) 100 ( D ) 120 5 .已知一个顺序存储的线性表, 设每个结点需要占 m 个存储单元,若第一个结点的地址为 da , 则第i 个结点的地址为:(A ) 7 .链表是一种采用( B )存储结构存储的线性表。 (A )顺序 (B )链式 (C )星式 (D )网状 8 .线性表若采用链式存储结构时,要求内存中可用存储单兀的地址: (D ) (A )必须是连续的 (B )部分地址必须是连续的 (C )一定是不连续的 (D )连续或不连续都可以 9 .线性表L 在_ ( B )情况下适用于使用链式结构实现。 A ) da+(i-1)*m B ) da+i*m 6.在具有n 个结点的单链表中,实现( A )遍历链表和求链表的第 i 个结点 C )删除开始结点 C ) da-i*m D ) da+(i+1)*m A )的操作,其算法的时间复杂度为 0(n )。 B )在地址为p 的结点之后插入一个结点 D ) 删除地址为p 的结点的后继结点

线性代数1-2章精选练习题

第一章 行列式 一、单项选择题 1.下列排列是5阶偶排列的是 ( ). (A) 24315 (B) 14325 (C) 41523 (D)24351 2.如果n 阶排列n j j j 21的逆序数是k , 则排列12j j j n 的逆序数是( ). (A)k (B)k n (C) k n 2 ! (D)k n n 2)1( 3. n 阶行列式的展开式中含1122a a 的项共有( )项. (A) 0 (B)2 n (C) )!2( n (D) )!1( n 4. 001001001001 000( ). (A) 0 (B)1 (C) 1 (D) 2 5. 0 001100000100100( ). (A) 0 (B)1 (C) 1 (D) 2 6.在函数10 3 23211112)(x x x x x f 中3x 项的系数是( ). (A) 0 (B)1 (C) 1 (D) 2 7. 若2 1 33 32 31 232221 131211 a a a a a a a a a D ,则 32 3133 31 2221232112 111311122222 2a a a a a a a a a a a a D ( ). (A) 4 (B) 4 (C) 2 (D) 2 8.若 a a a a a 22 2112 11,则 21 11 2212ka a ka a ( ).

(A)ka (B)ka (C)a k 2 (D)a k 2 9. 已知4阶行列式中第1行元依次是3,1,0,4 , 第3行元的余子式依次为 x ,1,5,2 , 则 x ( ). (A) 0 (B)3 (C) 3 (D) 2 10. 若5 7 3 4 111113263478 D ,则D 中第一行元的代数余子式的和为( ). (A)1 (B)2 (C)3 (D)0 11. 若2 23 5 1 011110403 D ,则D 中第四行元的余子式的和为( ). (A)1 (B)2 (C)3 (D)0 12. k 等于下列选项中哪个值时,齐次线性方程组 00321 321321x x kx x kx x kx x x 有非零解. ( ) (A)1 (B)2 (C)3 (D)0 二、填空题 1. n 2阶排列)12(13)2(24 n n 的逆序数是. 2.在六阶行列式中项261365415432a a a a a a 所带的符号是. 3.四阶行列式中包含4322a a 且带正号的项是 . 4.若一个n 阶行列式中至少有12 n n 个元素等于0, 则这个行列式的值等于 .

第二章线性表习题及答案

第二章线性表习题及答案 一、基础知识题 2.1 试描述头指针、头结点、开始结点的区别、并说明头指针和头结点的作用。 答:始结点是指链表中的第一个结点,也就是没有直接前趋的那个结点。 链表的头指针是一指向链表开始结点的指针(没有头结点时),单链表由头指针唯一确定,因此单链表可以用头指针的名字来命名。 头结点是我们人为地在链表的开始结点之前附加的一个结点。有了头结点之后,头指针指向头结点,不论链表否为空,头指针总是非空。而且头指针的设置使得对链表的第一个位置上的操作与在表其他位置上的操作一致(都是在某一结点之后)。 2.2 何时选用顺序表、何时选用链表作为线性表的存储结构为宜? 答:在实际应用中,应根据具体问题的要求和性质来选择顺序表或链表作为线性表的存储结构,通常有以下几方面的考虑: 1.基于空间的考虑。当要求存储的线性表长度变化不大,易于事先确定其大小时,为了节约存储空间,宜采用顺序表;反之,当线性表长度变化大,难以估计其存储规模时,采用动态链表作为存储结构为好。 2.基于时间的考虑。若线性表的操作主要是进行查找,很少做插入和删除操作时,采用顺序表做存储结构为宜;反之,若需要对线性表进行频繁地插入或删除等的操作时,宜采用链表做存储结构。并且,若链表的插入和删除主要发生在表的首尾两端,则采用尾指针表示的单循环链表为宜。 2.3 在顺序表中插入和删除一个结点需平均移动多少个结点?具体的移动次数取决于哪两个因素? 答:在等概率情况下,顺序表中插入一个结点需平均移动n/2个结点。删除一个结点需平均移动(n-1)/2个结点。具体的移动次数取决于顺序表的长度n以及需插入或删除的位置i。i 越接近n则所需移动的结点数越少。 2.4 为什么在单循环链表中设置尾指针比设置头指针更好? 答:尾指针是指向终端结点的指针,用它来表示单循环链表可以使得查找链表的开始结点和终端结点都很方便,设一带头结点的单循环链表,其尾指针为rear,则开始结点和终端结点的位置分别是rear->next->next 和rear, 查找时间都是O(1)。 若用头指针来表示该链表,则查找终端结点的时间为O(n)。 2.5 在单链表、双链表和单循环链表中,若仅知道指针p指向某结点,不知道头指针,能否将结点*p从相应的链表中删去?若可以,其时间复杂度各为多少? 答:我们分别讨论三种链表的情况。 1. 单链表。当我们知道指针p指向某结点时,能够根据该指针找到其直接后继,但是由于不知道其头指针,所以无法访问到p指针指向的结点的直接前趋。因此无法删去该结点。 2. 双链表。由于这样的链表提供双向链接,因此根据已知结点可以查找到其直接前趋和直接后继,从而可以删除该结点。其时间复杂度为O(1)。 3. 单循环链表。根据已知结点位置,我们可以直接得到其后相邻的结点位置(直接后继),又因为是循环链表,所以我们可以通过查找,得到p结点的直接前趋。因此可以删去p所指结点。其时间复杂度应为O(n)。 2.6 下述算法的功能是什么? LinkList Demo(LinkList L){ // L 是无头结点单链表 ListNode *Q,*P; if(L&&L->next){ Q=L;L=L->next;P=L;

线性代数第二章答案

第二章 矩阵及其运算 1 已知线性变换 ?????++=++=++=3 21332123 2113235322y y y x y y y x y y y x , 求从变量x 1 x 2 x 3到变量y 1 y 2 y 3的线性变换 解 由已知 ? ??? ?????? ? ?=???? ??22 1321323513122y y y x x x 故 ???? ?????? ? ?=???? ??-3211 221323513122x x x y y y ? ??? ?????? ??----=321423736 947y y y ?????-+=-+=+--=3 21332123 211423736947x x x y x x x y x x x y 2 已知两个线性变换 ?????++=++-=+=3 2133 2123 11542322y y y x y y y x y y x ?????+-=+=+-=3 233122 11323z z y z z y z z y 求从z 1 z 2 z 3到x 1 x 2 x 3的线性变换 解 由已知 ???? ?????? ? ?-=???? ??221321514232102y y y x x x ??? ? ?????? ??--???? ??-=32131 010 2013514232102z z z ??? ? ?????? ??----=32 1161109412316z z z

所以有?????+--=+-=++-=3 2133 2123 2111610941236z z z x z z z x z z z x 3 设???? ??--=111111111A ??? ? ??--=150421321B 求3AB 2A 及A T B 解 ??? ? ??---???? ??--???? ??--=-1111111112150421321111111111323A AB ???? ??----=???? ??---???? ??-=2294201722213211111111120926508503 ??? ? ??-=???? ??--???? ??--=092650850150421321111111111B A T 4 计算下列乘积 (1)??? ? ?????? ??-127075321134 解 ???? ?????? ??-127075321134???? ???+?+??+?-+??+?+?=102775132)2(71112374?? ? ? ??=49635 (2)???? ??123)321( 解 ??? ? ??123)321((132231)(10)

线性表 习题

第二章 一选择题 1.一个线性表第一个元素的存储地址是100,每个元素的长度为4,则第5个元素的地址是( ) A.110 B.116 C.100 D.120 2. 向一个有128个元素的顺序表中插入一个新元素并保持原来顺序不变,平均要移动()个元素。 A.64 B.63 C.63.5 D.7 3.在循环双链表的p所指接点之前插入s所指接点的操作是 A.p-> prior =s;s-> next t=p;p-> prior t->left=s;s-> prior =p-> prior; B. p-> prior =s;p-> prior -> next =s;s-> next =p;s-> prior =p-> prior; C.s-> next =p;s-> prior =p-> prior;p-> prior =s;p-> prior -> next =s; D.s-> next =p;s-> prior =p-> prior;p-> prior -> next =s;p-> prior =s; 4.从一个具有n个结点的单链表中查找其值等于x结点时,在查找成功的情况下,需平均比较()个结点。 A.n B.n/2 C.(n-1)/2 D.(n+1)/2 5.线性表是具有n个()的有限序列(n≠0) A.表元素 B.字符 C.数据元素 D.数据项 6.非空的循环单链表head的尾结点(由P指向)满足 A. p->next=NULL B. p=NULL C. p->next=head D.p=head 7.在一个单链表中已知q所指的结点是p所指结点的前驱结点,若在q和p之间插入s 结点,则执行( ) A. s->next=p->next;p->next=s; B.p->next=s->next;s->next=p; C. q->next=s;s->next=p; D.p->next=s;s->next=q; 8.已知一个顺序存储线性表,若第1个结点的地址d,第3个的地址是5d,则第n个结点的地址为( ) A.[2*(n-1)+1]*d B.2*(n-1)*d C.[2*(n-1)-1]*d D.(n+1)*d 9.在一个具有n个结点的有序单链表中插入一个新结点并仍然有序的时间复杂度是( ) A.O(1) B.O(n) C.O(n2) D.O(nlog2n) 10.如果最常用的操作是提取第i个结点及其前驱,则采用( )存储方式最节省时间。 A.单链表 B.顺序表 C.循环链表 D.双链表 11.在一个长度为n的顺序存储线性表中,向第i个元素(1≤i≤n)之前插入一个新元素时,需要从后向前依次后移( )个元素。 A.n-i B.n-i+1 C.n-i-1 D.i 12.在一个长度为n的顺序存储线性表中,删除第i个元素(0≤i≤n-1)时,需要从后向

线性代数第二章习题答案

习 题 2-1 1.由6名选手参加乒乓球比赛,成绩如下:选手1胜选手2、4、5、6而负于选手3;选手2胜选手4、5、6而负于选手1、3;选手3胜选手1、2、4而负于选手5、6;选手4胜选手5、6而负于选手1、2、3;选手5胜选手3、6而负于选手1、2、4;选手6胜选手2而负于选手1、3、4、5.若胜一场得1分,负一场得0分,使用矩阵表示输赢状况,并排序. 解: ????? ?? ? ? ? ??000010 100100110000001011 1110001110106543216 54321,选手按胜多负少排序为:6,5,4,3,2,1. 2.设矩阵???? ??-=???? ?? +-=2521 ,03231 z x y x B A ,已知B A =,求z y x ,,. 解:由于B A =得?????=-=+=-0253223z x y x ,解得:?? ? ??===211 z y x 。 习 题 2-2 1.设???? ??=0112A ,??? ? ??-=4021B ,求 (1)B A 52-; (2)BA AB -; (3)2 2B A -. 解:(1)??? ? ??--=???? ??--???? ??=???? ??--???? ??=-202892001050224402150112252B A ; (2)???? ??--=???? ??--???? ??--=???? ?????? ??--???? ??-???? ??=-2592041021820112402140210112BA AB ; (3)??? ? ??--=???? ??-???? ??=???? ??-???? ??--???? ?????? ??=-152441606112254021402101120112B A 22. 2.已知????? ??--=230412301321A ,??? ? ? ??---=052110 35123 4B ,求B A 23-. 解:??? ? ? ??----????? ??--=052110351234223041230 13 21 323B -A ??? ? ? ??----=????? ??----????? ??--=61941016151055011010422061024686901236903963 3.设??? ? ? ??----=????? ??=101012121234,432112 122121B A ,求

第二章_线性表(参考答案)

第二章线性表 一、填空题 1、数据逻辑结构包括线性结构、树型结构、图型结构这三种类型,树形结构和图形结构合称为非线性结构。 2、在线性结构中,第一个结点没有前驱结点,其余每个结点有且只有个前驱结点,最后一个结点没有后续结点,其余每个结点有且只有一个后续结点。 3、在顺序表中插入或删除一个元素,需要平均移动一半元素,具体移动的元素个数与插入或删除的位置有关。 4、在顺序表中,逻辑上相邻的元素,其物理位置一定相邻。在单链表中,逻辑上相邻的元素,其物理位置不一定相邻。 5、在带头结点的非空单链表中,头结点的存储位置由头指针指示,首元素结点的存储位置由头结点的next域指示,除首元素结点外,其它任一元素结点的存储位置由其直接前趋结点的next域指示。 6、阅读下列算法,并补充所缺内容。 void purge_linkst( ListNode *& la ) { // 从头指针为 la 的有序链表中删除所有值相同的多余元素,并释放被删结点空间ListNode *p,*q; if(la==NULL) return; q=la; p = la->link; while (p) { if (p && ___(1)p->data!=q->data___) {q=p; p = p->link;} else { q->link= ___(2)p->link___; delete(p); p=___(3)q->link___; } }//while }// purge_linkst 二、选择题 1、在数据结构中,从逻辑上可以把数据结构分成 C。 A、动态结构和静态结构 B、紧凑结构和非紧凑结构 C、线性结构和非线性结构 D、内部结构和外部结构 2、线性表的逻辑顺序与存储顺序总是一致的,这种说法 B。 A、正确 B、不正确 3、线性表若采用链式存储结构时,要求内存中可用存储单元的地址D。 A、必须是连续的 B、部分地址必须是连续的 C、一定是不连续的 D、连续或不连续都可以 4、在以下的述叙中,正确的是B。 A、线性表的线性存储结构优于链表存储结构 B、二维数组是其数据元素为线性表的线性表 C、栈的操作是先进先出 D、队列的操作方式是先进后出 三、综合题 1、已知L是无表头结点的单链表,且P结点既不是首元结点,也不是尾元结点,试从下列提供的答案中选择合适的语句序列。 A、在P结点后插入S结点的语句序列是((4)、(1)); B、在P结点前插入S结点的语句序列是((7)、(11)、(8)、(4)、(1)); C、在表首插入S结点的语句序列是((5)、(12));

第2章线性表习题参考答案

一、选择题 1. D 2. B 3. B 4. B 5. B 6. B 7. D 8. B 9. C 10. B 11. C 12. C 13. B 14. D 15. A 16. B 17. B 18. C 19. A 20. C 21. D 22. A 23. A 24. A 二、填空题 1. 首元素其直接前驱结点的链域的值 2. HL→next =NULL; HL=HL→next 3. 有限、一对一 4. O(1) 随机存取 5. 表中一半表长和该元素在表中的位置 6. 必定不一定 7. O(1) O(n) 8. 前驱结点的地址 O(n) 9. n-i+1 n-i 10. s->left=p p->right 三、判断题 1. × 2. × 3. × 4. × 5. × 6. × 7. √ 8. × 9. × 10. × 11. × 四、简答题 1. 线性表为:(78,50,40,60,34,90) 2. (36, 12, 8, 50, 25, 5, 15) 3. 解答: 尾指针是指向终端结点的指针,用它来表示单循环链表可以使得查找链表的开始结点和终端结点都很方便,设一带头结点的单循环链表,其尾指针为rear,则开始结点和终端结点的位置分别是rear->next->next和rear, 查找时间都是O(1)。

若用头指针来表示该链表,则查找终端结点的时间为O(n)。 五、编程题 1. 解答:由于在单链表中只给出一个头指针,所以只能用遍历的方法来数单链表中的结点个数了。算法如下: int ListLength ( LinkList L ) { int len=0 ; ListNode *p; p=L; //设该表有头结点 while ( p->next ) { p=p->next; len++; } return len; } 2. int searchmin(linklist l) { int min; int *p; p=l; min=p->data; p=p->next; while (p->next< >nil) { if (min>p->data) min=p->data; p=p->next; } return min; } 3. int searchmax(linklist l) { int max; int *p; p=l; max=p->data; p=p->next; while (p->next< >nil) { if (maxdata) max=p->data; p=p->next; } return max; } 4. 顺序表:要将该表逆置,可以将表中的开始结点与终端结点互换,第二个结点与倒数第二个结点互换,如此反复,就可将整个表逆置了。 算法如下: // 顺序表结构定义同上题 void ReverseList( Seqlist *L) { DataType temp ; //设置临时空间用于存放data int i; for (i=0;i<=L->length/2;i++)//L->length/2为整除运算 { temp = L->data[i]; //交换数据 L -> data[ i ] = L -> data[ L -> length-1-i]; L -> data[ L -> length - 1 - i ] = temp; }

线性表 答案

数据结构与算法上机作业第二章线性表

一、选择题 1、若长度为n的线性表采用顺序存储结构,在其第i个位置插入一个新的元素算法的时间复杂度为 C 。 A. O(log2n) B. O(1) C. O(n) D. O(n2) 2、以下关于线性表的说法中,不正确的是 C 。 A. 线性表中的数据元素可以是数字、字符、结构等不同类型 B. 线性表中包含的数据元素个数不是任意的 C. 线性表中的每一个结点都有且只有一个直接前驱和直接后继 D. 存在这样的线性表:表中各结点都没有直接前驱和直接后继 3、在有n个结点的顺序表上做插入、删除结点运算的时间复杂度为 B 。 A. O(1) B. O(n) C. O(n2) D. O(log2n) 4、等概率情况下,在有n个结点的顺序表上做插入结点操作,需平均移动的结点数目为 C 。提示:插入的位置有n+1个,移动总数为:1+2+3+……+n A. n B. (n-1)/2 C. n/2 D. (n+1)/2 5、在一个长度为n的顺序存储的线性表中查找值为x的元素时,平均查找长度(及x同元素的平均比较次数,假定查找每个元素的概率都相等)为 C 。 A. n B. n/2 C. (n+1)/2 D. (n-1)/2 6、在顺序表中,只要知道 D ,就可以求出任一结点的存储地址。 A. 基地址 B. 结点大小 C. 向量大小 D. 基地址和结点大小 7、将两个各有n个元素的有序表归并为一个有序表,其最少的比较次数是 A 。 A. n B. 2n-1 C. 2n D. n-1 8、线性表采用链表存储时其存储地址要求 D 。 A. 必须是连续的 B. 部分地址必须是连续的 C. 必须是不连续的 D. 连续的和不连续的都可以 9、下面关于线性表的描述中,错误的是 B 。 A. 线性表采用顺序存储,必须占用一片连续的存储单元 B. 线性表采用顺序存储,便于进行插入和删除操作 C. 线性表采用链式存储,不必占用一片连续的存储单元 D. 线性表采用链式存储,便于插入和删除操作 10、向具有n个结点的有序单链表中插入一个新结点并仍然有序的时间复杂度是 B A. O(1) B. O(n) C. O(n2) D. O(log2n) 11、在一个带头结点的单链表HL中,若要向表头插入一个由指针p指向的结点,则执行的语句是 D 。 A. HL=p; p->next=HL; B. p->next=HL; HL=p; C. p->next=HL; p=HL; D. p->next=HL->next; HL->next=p; 12、在一个单链表HL中,若要删除由指针q所指向结点的后继结点,则执行的语句是C 。 A. p=q->next; p->next=q->next; B. p=q->next; q->next=p; C. p=q->next; q->next=p->next; D. q->next=q->next->next; q->next=q; 13、设有编号为1, 2, 3, 4的4辆列车,顺序进入一个栈结构的站台,下列不可能的出栈顺序为 D 。 A. 1234 B. 1243 C. 1324 D. 1423