答案:(1)s-〉next=p-〉next (2)p->next=s
3、函数ListDelete_sq实现顺序表删除算法,请在空格处将算法补充完整.
int ListDelete_sq(Sqlist *L,int i){ int k;
if(i<1||i>L—>length) return ERROR;
for(k=i-1;k〈L-〉length—1;k++)
L-〉slist[k]= (1) ;
(2) ; return OK; }
答案:(1)L-〉slist[k+1] (2) ——L-〉Length 4、函数实现单链表得删除算法,请在空格处将算法补充完整。
int ListDelete(LinkList L,int i,ElemType *s){ LNode *p,*q; int j; p=L;j=0;
while(( (1) )&&(j〈i-1)){ p=p-〉next;j++; }
if(p—〉next==NULL||j>i-1) return ERROR; q=p-〉next; (2) ; *s=q-〉data; free(q); return OK; }/*listDelete*/
答案:(1)p—〉next!=NULL (2)p—〉next=q—>next 5、写出算法得功能.
int L(head){ ?node * head; ?int n=0; node *p; ??p=head;
??while(p!=NULL) ?{ p=p-〉next; ?? n++; ? }
??return(n); ?}
答案:求单链表head得长度 五、综合题
1、编写算法,实现带头结点单链表得逆置算法. 答案:void invent(Lnode *head)
{Lnode *p,*q;
if(!head->next) return ERROR;
p=head—〉next; q=p—〉next; p—〉next =NULL; while(q)
{p=q; q=q—〉next; p->next=head—〉next; head—〉next=p;} }
2、有两个循环链表,链头指针分别为L1与L2,要求写出算法将L2链表链到L1链表之后,且连接后仍保持循环链表形式。
答案:void merge(Lnode *L1, Lnode *L2)
{Lnode *p,*q ;
while(p->next!=L1)
p=p->next;
while(q->next!=L2)
q=q-〉next;
q->next=L1; p—〉next =L2; }
3、设一个带头结点得单向链表得头指针为head,设计算法,将链表得记录,按照data域得值递增排序。
答案:void assending(Lnode *head)
{Lnode *p,*q , *r, *s;
p=head-〉next; q=p—〉next; p—>next=NULL; while(q)
{r=q; q=q-〉next;
if(r-〉data<=p-〉data)
{r->next=p; head-〉next=r; p=r; } else
{while(!p && r->data〉p-〉data)
{s=p; p=p—〉next; } r—>next=p; s—〉next=r;} p=head->next; }
}
4、编写算法,将一个头指针为head不带头结点得单链表改造为一个单向循环链表,并分析算法得时间复杂度。 答案:
void linklist_c(Lnode *head) {Lnode *p; p=head; if(!p) return ERROR;
while(p-〉next!=NULL)
p=p->next; p—〉next=head; }
设单链表得长度(数据结点数)为N,则该算法得时间主要花费在查找链表最后一个结点上(算法中得while循环),所以该算法得时间复杂度为O(N).
5、已知head为带头结点得单循环链表得头指针,链表中得数据元素依次为(a1,a2,a3,a4,…,an),A为指向空得顺序表得指针。阅读以下程序段,并回答问题: (1)写出执行下列程序段后得顺序表A中得数据元素; (2)简要叙述该程序段得功能。
if(head->next!=head) {
p=head—>next; A—>length=0;
while(p—〉next!=head) {
p=p—〉next;
A—〉data[A->length ++]=p—〉data; if(p->next!=head)p=p—>next; }
} 答案:
(1) (a2, a4, …, ) (2)将循环单链表中偶数结点位置得元素值写入顺序表A
6、设顺序表va中得数据元数递增有序。试写一算法,将x插入到顺序表得适当位置上,以保持该表得有序性。 答案:
void Insert_sq(Sqlist va[], ElemType x) {int i, j, n; n=length(va[]); if(x>=va[i])
va[n]=x; else
{i=0;
while(x〉va[i]) i++; for(j=n—1;j>=I;j--)
va[j+1]=va[j]; va[i]=x; } n++; }
7、假设线性表采用顺序存储结构,表中元素值为整型。阅读算法f2,设顺序表L=(3,7,3,2,1,1,8,7,3),写出执行算法f2后得线性表L得数据元素,并描述该算法得功能。
void f2(SeqList *L){
int i,j,k; k=0;
for(i=0;i〈L—>length;i++){
for(j=0;j
?? if(j==k){
if(k!=i)L—>data[k]=L—〉data[i];
???k++; ? }
}
L-〉length=k; }
答案:
(3,7,2,1,8) 删除顺序表中重复得元素
8、已知线性表中得元素以值递增有序排列,并以单链表作存储结构。试写一算法,删除表中所有大于x且小于y得元素(若表中存在这样得元素)同时释放被删除结点空间。 答案:
void Delete_list(Lnode *head, ElemType x, ElemType y) {Lnode *p, *q; if(!head) return ERROR;
p=head; q=p; while(!p)
{if(p->data>x) && (p—>data if(p==head) {head=p—〉next; free(p); p=head; q=p; } else {q->next=p->next; free(p); p=q—>next; } else {q=p; p=p->next; } } } 9、在带头结点得循环链表L中,结点得数据元素为整型,且按值递增有序存放。给定两个整数a与b,且a〈b,编写算法删除链表L中元素值大于a且小于b得所有结点。 第三章 栈与队列 一、选择题 1、一个栈得输入序列为:a,b,c,d,e,则栈得不可能输出得序列就是( )。 A、 a,b,c,d,e B、 d,e,c,b,a ? C、 d,c,e,a,b ?D、 e,d,c,b,a 2、判断一个循环队列Q(最多n个元素)为满得条件就是( )。 A、 Q->rear==Q-〉front ?? B、 Q—〉rear==Q-〉front+1 C、 Q—>front==(Q—〉rear+1)%n? ??D、 Q->front==(Q->rear—1)%n 3、设计一个判别表达式中括号就是否配对得算法,采用( )数据结构最佳。 A、 顺序表 B、 链表 ? ?C、 队列 D、 栈 4、带头结点得单链表head为空得判定条件就是( ). A、 head==NULL ?B、 head—>next==NULL?? C、 head-〉next!=NULL ?D、 head!=NULL 5、一个栈得输入序列为:1,2,3,4,则栈得不可能输出得序列就是( )。 A、 1243 B、 2134 ? C、 1432 D、 4312? E、 3214 6、若用一个大小为6得数组来实现循环队列,且当rear与front得值分别为0,3。当从队列中删除一个元素,再加入两个元素后,rear与front得值分别为( )。 A、 1与5 ? B、 2与4 ??C、 4与2? D、 5与1 7、队列得插入操作就是在( )。 A、 队尾?? ?B、 队头 ??C、 队列任意位置 D、 队头元素后 8、循环队列得队头与队尾指针分别为front与rear,则判断循环队列为空得条件就是( )。 A、 front==rear?? B、 front==0 C、 rear==0? ? D、 front=rear+1 9、一个顺序栈S,其栈顶指针为top,则将元素e入栈得操作就是( )。 A、 *S->top=e;S-〉top++; ??B、 S->top++;*S-〉top=e; C、 *S—>top=e ? ??D、 S->top=e; 10、表达式a*(b+c)-d得后缀表达式就是( )。 A、 abcd+- B、 abc+*d-? C、 abc*+d— ?D、 —+*abcd 11、将递归算法转换成对应得非递归算法时,通常需要使用( )来保存中间结果。 A、 队列 ?B、 栈 C、 链表 ? D、 树 12、栈得插入与删除操作在( ). A、 栈底 B、 栈顶 C、 任意位置 ?D、 指定位置 13、五节车厢以编号1,2,3,4,5顺序进入铁路调度站(栈),可以得到( )得编组。 A、 3,4,5,1,2? B、 2,4,1,3,5 ? C、 3,5,4,2,1 ??D、 1,3,5,2,4 14、判定一个顺序栈S(栈空间大小为n)为空得条件就是( )。 A、 S—>top==0 ? B、 S->top!=0? C、 S->top==n? ?D、 S—〉top!=n 15、在一个链队列中,front与rear分别为头指针与尾指针,则插入一个结点s得操作为( )。 A、 front=front—>next ? B、 s->next=rear;rear=s C、 rear—〉next=s;rear=s;? D、 s-〉next=front;front=s; 16、一个队列得入队序列就是1,2,3,4,则队列得出队序列就是( )。 ?A、 1,2,3,4 ? B、 4,3,2,1 C、 1,4,3,2 ???D、 3,4,1,2 17、依次在初始为空得队列中插入元素a,b,c,d以后,紧接着做了两次删除操作,此时得队头元素就是( ). A、 a B、 b ? ?C、 c ? ?D、 d 18、正常情况下,删除非空得顺序存储结构得堆栈得栈顶元素,栈顶指针top得变化就是( )。 A、 top不变 ? B、 top=0 C、 top=top+1? D、 top=top-1 19、判断一个循环队列Q(空间大小为M)为空得条件就是( )。 A、 Q->front==Q—〉rear ?B、 Q-〉rear-Q-〉front-1==M? ? C、 Q—〉front+1=Q-〉rear ??D、 Q-〉rear+1=Q—〉front 20、设计一个判别表达式中左右括号就是否配对出现得算法,采用( )数据结构最佳。 A、 线性表得顺序存储结构 B、 队列??C、 栈 ?D、 线性表得链式存储结构 21、当用大小为N得数组存储顺序循环队列时,该队列得最大长度为( )。 A、 N ? B、 N+1???C、 N-1 ?D、 N-2 22、队列得删除操作就是在( )。 A、 队首 ? ?B、 队尾 ? C、 队前? ?D、 队后 23、若让元素1,2,3依次进栈,则出栈次序不可能就是( )。 A、 3,2,1 ??B、 2,1,3 C、 3,1,2 ??D、 1,3,2 24、循环队列用数组A[0,m—1]存放其元素值,已知其头尾指针分别就是front与rear,则当前队列中得元素个数就是( )。 ?A、 (rear-front+m)%m? ?B、 rear—front+1 ? C、 rear-front-1????D、 rear-front 25、在解决计算机主机与打印机之间速度不匹配问题时,通常设置一个打印数据缓冲区,主机将要输出得数据依次写入该缓冲区,而打印机则从该缓冲区中取走数据打印。该缓冲区应该就是一个( )结构。 A、 堆栈 ?B、 队列 ?C、 数组 ?? D、 线性表 26、栈与队列都就是( ). A、 链式存储得线性结构 ? B、 链式存储得非线性结构 C、 限制存取点得线性结构 ? D、 限制存取点得非线性结构 27、在一个链队列中,假定front与rear分别为队头指针与队尾指针,删除一个结点得操作就是( ). A、 front=front—〉next B、 rear= rear—〉next ? C、 rear—〉next=front?? D、 front—>next=rear 28、队与栈得主要区别就是( )。 A、 逻辑结构不同 ? ?B、 存储结构不同 C、 所包含得运算个数不同 ? D、 限定插入与删除得位置不同 二、填空题 1、设栈S与队列Q得初始状态为空,元素e1,e2,e3,e4,e5,e6依次通过栈S,一个元素出栈后即进入队列Q,若6个元素出队得序列就是e2,e4,e3,e6,e5,e1,则栈得容量至少应该就是 。 答案:3 2、一个循环队列Q得存储空间大小为M,其队头与队尾指针分别为front与rear,则循环队列中元素得个数为: 。 答案:(rear—front+M)%M 3、在具有n个元素得循环队列中,队满时具有 个元素。 答案:n-1 4、设循环队列得容量为70,现经过一系列得入队与出队操作后,front为20,rear为11,则队列中元素得个数为 . 答案:61 5、已知循环队列得存储空间大小为20,且当前队列得头指针与尾指针得值分别为8与3,且该队列得当前得长度为_______. 三、判断题 1、栈与队列都就是受限得线性结构。? 2、在单链表中,要访问某个结点,只要知道该结点得地址即可;因此,单链表就是一种随机存取结构.? 3、以链表作为栈得存储结构,出栈操作必须判别栈空得情况.? 四、程序分析填空题 1、已知栈得基本操作函数: ?int InitStack(SqStack *S); //构造空栈 int StackEmpty(SqStack *S);//判断栈空 int Push(SqStack *S,ElemType e);//入栈