sum二s;
解:
0(n2)
(3)T二A;
A=B;
B=T;
解:
o⑴
(4)si(intn)
{intp=lts=0;
for(i=l;i<=n;i++)
{p*=i;s+=p;}
return(s);
}
0(n)
(5)s2(intn)
x二0;
y二0;
for(k=l;k<=n;k++)
x++;
for(i=l;i<=n;i++)for(j=l;j<=n;j++)y++;
解:
0(n2)
五.根据二元组关系,画出对应逻辑图形的草图,指出它们属于何种数据结构。
(1)A=(D,R),其中:
D={atb,c,d>e},
R={}
解:
ao6
cde
o°0
属于集合
(2)B=(D.R),其中:
D={a,b,ctdte,f},R={r}
R={,,,,}(尖括号表示结点之间关系是有向的)
解:
(D~~KD_KD~~KD~
属于线性结构。
(3)F=(D,R),其中:
D二{50,25.64,57,82.36.75.55},R={r)
R={<50,25>,<50,64>,<25,36>,<64,57>,<64,82>•<57.55>,<57,75»
属于树结构
(4)C=(D,R),其中:
D二{1,2,3.4.5.6},R二{r}
R={(1,2),(2.3),(2,4),(3.4),(3,5),(3,6),(4,5),(4,6))(园括号表示结点之间关系是有向的)
解:
2
属于图结构
(5)E=(D,R),其中:
D={a,b,ctd,e.ftgth}♦R={r}
R=Kd,b>ft,,.,}解:
属于树结构。
单元练习2
1.判断题(下列各题,正确的请在前面的括号打错误的打X)
(X)
(1)线性表的链式存储结构优于顺序存储。
(X)
(2)链表的每个结点都恰好包含一个指针域。
(7)(3)在线性表的链式存储结构中,逻辑上相邻的两个元素在物理位置上并不一定紧邻。
(X)(4)顺序存储方式的优点是存储密度大,插入、删除效率高。
(X)(5)线性链表的删除算法简单,因为当删除链中某个结点后,计算机会自动地将后续的各个单元向前移动。
(X)(6)顺序表的每个结点只能是一个简单类型,而链表的每个结点可以是一个复杂类型。
(V)(7)线性表链式存储的特点是可以用一组任意的存储单元存储表中的数据元素。
(V)(8)线性表采用顺序存储,必须占用一片连续的存储单元。
(X)(9)顺序表结构适宜于进行顺序存取,而链表适宜于进行随机存取。
(X)(10)插入和删除操作是数据结构中最基本的两种操作,所以这两种操作在数组中也经常使用。
2.填空题
(1)顺序表中逻辑上相邻的元素在物理位置上必须相连。
(2)线性表中结点的集合是有限的,结点间的关系是一对一关系。
(3)顺序表相对于链表的优点是:
节省存储和随机存取。
(4)链表相对于顺序表的优点是:
插入、删除方便。
(5)采用顺序存储结构的线性表叫顺序表。
(6)顺序表中访问任意一个结点的时间复杂度均为0仃)。
(7)链表相对于顺序表的优点是插入、删除方便;缺点是存储密度小。
(8)在双链表中要删除已知结点*P,其时间复杂度为0
(1)。
(9)在单链表中要在已知结点*P之前插入一个新结点,需找到科的直接前趋结点的地址,
其查找的时间复杂度为O(n)。
(10)单链表中需知道头指针才能遍历整个链表。
(11)性表中第一个结点没有直接前趋,称为开始结点。
(12)在一个长度为n的顺序表中删除第i个元素,要移动n-i个元素。
(13)在一个长度为n的顺序表中,如果要在第i个元素前插入一个元素,要后移n-i+1个元素。
(14)在无头结点的单链表中,第一个结点的地址存放在头指针中,而其它结点的存储地
址存放在前趋结点的指针域中。
(15)当线性表的元素总数基本稳定,且很少进行插入和删除操作,但要求以最快速度存取线性表中的元素时,应采用顺序存储结构。
(16)在线性表的链式存储中,元素之间的逻辑关系是通过指针决定的。
(17)在双向链表中,每个结点都有两个指针域,它们一个指向其前趋结点,另一
个指向其_后继结点。
(18)对一个需要经常进行插入和删除操作的线性表,采庠维式存储结构为宜。
(19)双钱表中,设p是指向其中待删除的结点,则需要执行的操作为:
p->prior->next=p->next。
(20)在如图所示的链表中,若在指针P所在的结点之后插入数据域值为a和b的两个结点,则可用下列两个语句:
S->next->next=P->next;和P->next=S;来实现该操作。
3.选择题
(1)在具有n个结点的单链表中,实现(
A.遍历链表或求链表的第i个结点
C.删除开始结点
)的操作,其算法的时间复杂度都是05)。
B.在地址为P的结点之后插入一个结点D.删除地址为P的结点的后继结点
(2)设a、b、c为三个结点,p、10、20分别代表它们的地址,则如下的存储结构称为(B)。
10
A.循环链表B.单链表
(3)单钱表的存储密度(C)。
A.大于1B.等于1
C.双向循环链表
D.双向链表
C.小于1
D.不能确定
(4)已知一个顺序存储的线性表,设每个结点占m个存储单元,若第一个结点的地址为B,则第i个结点的地址为(A)。
A.
D.B+(i+l)*m
B)o
D.0(log2n)
B+(iT)*mB.B+i*mC.B-i*m
(5)在有n个结点的顺序表上做插入、删除结点运算的时间复杂度为(
2.
A・0
(1)B・0(n)C.0(F)
P=NULL
D.P->Rlink=L
(6)设Llink,Rlink分别为循环双钱表结点的左指针和右指针,则指针P所指的元素是双循环链表L的尾元素的条件是(D)。
A.P==LB.P->Llink==LC.
(7)两个指针P和Q,分别指向单链表的两个元素,P所指元素是Q所指元素前驱的条件是(B)。
A.P->next==Q->nextB.P->next=QC.Q->next==PD.P==Q
(8)用钱表存储的线性表,其优点是(C)。
A.便于随机存取B.花费的存储空间比顺序表少
C.便于插入和删除D.数据元素的物理顺序与逻辑顺序相
同
(9)在单链表中,增加头结点的目的是(C)。
A.使单链表至少有一个结点
C.方便运算的实现
结构
(10)下面关于线性表的叙述中,错误的是(
A.顺序表必须占一片地址连续的存储单元
C.链表不必占用一片地址连续的存储单元
B.标志表中首结点的位置
D.说明该单链表是线性表的链式存储
D)关系。
B.顺序表可以随机存取任一元素
D.链表可以随机存取任一元素
(11)L是线性表,已知LengthList(L)的值是5,经DelList(L,2)运算后♦LengthList(L)的值是(C)。
A.2B.3C.4D.5
(12)单链表的示意图如下:
L
指向链表Q结点的前趋的指针是(B)。
A.LB・PC.QD・R
(13)设p为指向单循环钱表上某结点的指针,则*p的直接前驱(C)。
A.找不到B.查找时间复杂度为0
(1)
C.查找时间复杂度为0(n)D.查找结点的次数约为n
(14)等概率情况下,在有n个结点的顺序表上做插入结点运算,需平均移动结点的数目为(C)。
A.n
C.n/2
(15)在下列链表中不能从当前结点出发访问到其余各结点的是(
A.双向链表
B.单循环链表C.单链表
D.(n+l)/2
C)。
D.双向循环链表
(16)在顺序表中,只要知道(D),就可以求出任一结点的存储地址。
A.基地址
B.结点大小
C.向量大小D.基地址和结点大小
(17)在双链表中做插入运算的时间复杂度为(A)。
A.0
(1)
B.0(n)
C.0(n2)
(18)链表不具备的特点是(A)。
A.随机访问
C.插入删除时不需移动元素
(19)以下关于线性表的论述.不正确的为(
D.0(logm)
B.不必事先估计存储空间
D.所需空间与线性表成正比
C)。
A.线性表中的元素可以是数字、字符.记录等不同类型
B.线性顺序表中包含的元素个数不是任意的
C.线性表中的每个结点都有且仅有一个直接前趋和一个直接后继
D.存在这样的线性表,即表中没有任何结点
(20)在(B)的运算中,使用顺序表比链表好。
A.插入B.根据序号查找C.删除D.根据元素查找
4.分析下述算法的功能
(1)ListNodc*Demol(LinkListL.ListNode*p)
{〃L是有头结点的单链表
ListNode*q=L->next;
While(q&&q・>i】cxt!
=p)
q=q->next;
if(q)
returnq;
else
Error(“*pnotinLM);
}
(2)voidDemo2(ListNode*p,ListNode*q)
{//p,*q是链表中的两个结点
DataT^-petemp;
temp=p->data;
p->data=q->data:
q->data=temp;
}
解:
(1)返回结点和的直接前趋结点地址。
(2)交换结点和和结点*q(p和q的值不变)。
5.程序填空
(1)已知线性表中的元素是无序的,并以带表头结点的单链表作存储。
试写一算法,删除表中所有大于min,小于max的元素,试完成下列程序填空。
Voiddelete(lklisthead;datatypemin,max)
{q=head->next;
while(p!
二NULL)
{if((p->data<=min)(p->dst3>二!
nax)
(q=p;p-p->next;}
else
{q->next=p->next;
delete(p)
p=q->next;}
}
(2)在带头结点head的单链表的结点a之后插入新元素x,试完成下列程序填空。
structnode
{elemtypedata;
node水next;
};
voidlkinsert(node*head,elemtypex)
{node*s,*p;
s=newnode;
s->data=x;
p=head->next;
while(p!
=NULL)&&(p->data!
=a)
p二p_〉next;
if(p==NULL)
cout«H不存在结点a!
";
else{s->next二p->next;
p->next二s;
6.算法设计题
(1)写一个对单循环链表进行遍历(打印每个结点的值)的算法,已知链表中任意结点的地址为P。
解:
voidShow(ListNode*P)
{ListNode*t=P;
do
{printf("%cM,t->data):
t=t->rear;
}
while(t1=P):
}
(2)对绐定的带头结点的单链表L,编写一个删除L中值为x的结点的直接前趋结点的算法。
解:
voiddelete(ListNode*L)
{ListNode*p=L.*q;
if(L->next->data—X)
printf(“值为x的结点是第一个结点,没有直接前趋结点可以删除”return;
}
For(p->next->data!
=X;q=p;p=p->next):
//删除指针p所指向的结点q->next=p->next;
deletep;
}
(3)已知一个单向链表,编写一个函数从单链表中删除自第i个结点起的k个结点。
解:
voidDel(node*head,inti,intk)
node*p.*q;
intj;
//删除前k个元素
//p指向要删除的结点
//p指向要刪除的结点的前一个结点
//q指向要删除的结点
if(i==l)
for(j=l;j<=k;j++)
{
p二head;head-head->next;deletep;
}
else
{
p=head;
for(j=l;jUi-2;j++)p=p->next;
for(j=l;j<=k;j++)
{
q=p->next;p->next=q->next;deleteq;
}
}
}
(4)有一个单向链表(不同结点的数据域值可能相同),其头指针为head,编写一个函数计算值域为X的结点个数。
解:
〃本题是遍历单链表的每个结点,每遇到一个结点,结点个数加1,结点个数存储在变量n中。
实现本題功能的函数如下:
intcounter(head)
node*head;{node*p;
intn二0;
p=head;
while(p!
=NULL)
{if(p->data==x)
n++;
p=p->next;
}
return(n);
}
(5>有两个循环单向链表,链头指针分别为headl和head2,编写一个函数将链表headl到链表head2,后的链表仍是循环链表。
解:
//本题的算法思想是:
先找到两链表的尾指针,将第一个链表的尾指针与第二个链表的头结点起来,使之成为循环的。
函数如下:
node*1ink(node*headlt*head2)
{node水p・*q;
p=headl:
while(p->next!
=head1)
p=p->next;
q=head2;
while(q->next!
=head2)
q二q->next;
p->next=head2;
q->next=headl;
return(headl);
单元练习3
1.判断题(下列各题,正确的请在前面的括号打错误的打X)
(7)
(1)栈是运算受限制的线性表。
(V)
(2)在栈空的情况下,不能作出栈操作,否则产生下溢出。
(X)(3)栈一定是顺序存储的线性结构。
(V)(4)栈的特点是“后进先出"。
(><)(5)空栈就是所有元素都为0的栈。
(乂)(6)在C或C++语言中设顺序栈的长度为MAXLEN,则top=MAXLEN时表示队满。
(V)(7)链栈与顺序栈相比,其特点之一是通常不会出现栈满的情况。
(乂)(8)一个栈的输入序列为:
A,B,C,D,可以得到输出序列:
C,A,B,D。
(乂)(9)递归定义就是循环定义。
(V)(10)将十进制数转换为二进制数是栈的典型应用之一。
2.填空题
(1)在栈结构中,允许插入、删除的一端称为栈顶。
(2)在顺序栈中,当栈顶指针top=-l时,表示Z.
(3)在有n个元素的栈中,进栈操作的时间复杂度为0
(1)。
(4)在栈中,出栈操作的时间复杂度为:
0
(1)o
(5)已知表达式,求它的后缀表达式是栈的典型应用。
(6)在一个链栈中,若栈顶指针等于NULL,则表示栈空。
(7)向一个栈顶指针为top的链栈插入一个新结点*卩时,应执行p->next-t,op:
和top=p;操作。
(8)顺序栈S存储在数组S->data[0..MAXLEN-1]中,进栈操作时要执行的语句有:
S->top++。
(或=S->top+l)
(9)链栈LS,指向栈顶元素的指针是LS->next。
(10)从一个栈删除元素时,首先取出栈顶元素•然后再移动栈顶指针。
(11)由于链栈的操作只在链表的头部进行,所以没有必要设置头结点。
(12)已知顺序栈S,在对S进行进栈操作之前首先要判断栈是介满。
(13)已知顺序栈S,在对S进行出栈操作之前首先要判断栈是否空。
(14)若存空间充足,链栈可以不定义栈满运算。
(15)链栈LS是空的条件是LS->next=NULL。
(16)链栈LS的栈