当前位置:文档之家› 数据结构(C语言版)习题及答案第二章

数据结构(C语言版)习题及答案第二章

习题2.1选择题1、线性表的顺序存储结构是一种(A)的存储结构,线性表的链式存储结构是一种(B)的存储结构。

A、随机存取B、顺序存取C、索引存取D、散列存取2、对于一个线性,既要求能够进行较快的插入和删除,又要求存储结构能够反映数据元素之间的逻辑关系,则应该选择(B)。

A、顺序存储方式B、链式存储方式C、散列存储方式D、索引存储方式3、已知,L是一个不带头结点的单链表,p指向其中的一个结点,选择合适的语句实现在p结点的后面插入s结点的操作(B)。

A、p->next=s ; s->next=p->next ;B、s->next=p->next ; p->next=s ;C、p->next=s ; s->next=p ;D、s->next=p ; p->next=s ;4、单链表中各结点之间的地址( C D)。

A、必须连续B、部分地址必须连续C、不一定连续D、连续与否都可以5、在一个长度为n的顺序表中向第i个元素(0<i<=n+1)之前插入一个新元素时,需向后移动(B)个元素。

A、n-iB、n-i+1C、n-i-1D、i2.2填空题1、顺序存储的长度为n的线性表,在任何位置上插入和删除操作的时间复杂度基本上都一样。

插入一个元素大约移动表中的(n/2)个元素,删除一个元素时大约移动表中的((n-1)/2)个元素。

2、在线性表的顺序存储方式中,元素之间的逻辑关系是通过(物理顺序)来体现的;在链式存储方式,元素之间的逻辑关系是通过(指针)体现的。

3、对于一个长度为n的单链表,在已知的p结点后面插入一个新结点的时间复杂度为(o(1)),在p结点之前插入一个新结点的时间复杂度为(o(n)),在给定值为e的结点之后插入一个新结点的时间复杂度为(o(n))。

4、在双向链表中,每个结点包含两个指针域,一个指向(前驱)结点,另一个指向(后继)结点。

5、对于循环链表来讲,逐个访问各个结点的结束判断条件是(设P为指向结点的指针,L为链表的头指针,则p->next= =L)。

2.3读下面的程序段,画出执行过程的示意图及所完成的功能。

1、 # define N 6void main ( ){ ListSq L ;int A[ N ];int i , elem ;InitList(L); //初始化函数for ( int j=0; j<N; j++)scanf("%d",&A[ j ]) ;for ( int m=0; m<N; m++)InsertList ( L , m ,A[m]) ;PrintList( L ) ; // 输出函数}L.e[0]L.e[1]L.e[2]L.e[3]L.e[4]L.e[5] 1题示意图L2题示意图功能:先初始化一个顺序表,然后根据数组A中元素的顺序创建顺序表,并输出顺序表的全部元素。

2、 Lnode *CreateList( ){ Lnode *L,*S;int x,y;L=malloc(sizeof(Lnode));L->data=x;s=malloc(sizeof(Lnode));s->data=y;L->next=s;s->next=NULL;return L;}功能:创建一个两个结点的不带头结点的单链表,两个结点的值分别为X和Y,L为单链表的头指针。

2.4 算法题1、编写在两种存储方式下,删除线性表中多余的值相同元素的算法。

解:顺序存储方式下:void del(ListSq &L){ int i=0;while (i<L.len-1){ int j=i+1;while (j<L.len)if (L.e[i]= =L.e[j]){ for (int k=j+1;k<L.len;k++)L.e[k-1]=L.e[k];L.len--;}else j++;i++;}}链式存储方式下:void del(Lnode *L){ Lnode *p=L->next;while (p->next!=NULL){ Lnode *q=p->next;Lnode *r=p;while (q!=NULL)if (q->data= =p->data){ r->next=q->next; free(q); q=r->next; }else {r=q; q=q->next; }p=p->next;}}2、已知,顺序表的元素类型为整型,编写将该顺序表分成两个顺序表的算法,一个存放所的奇数元素,另一个存放所的偶数元素。

解:void fenSq(ListSq L, ListSq &La, ListSq &Lb ){ int j=0,k=0;for (int i=0;i<L.len;i++)if (L.e[i]%2= =0){ Lb.e[j]=L.e[i]; j++; }else { La.e[k]=L.e[i]; k++; }La.len=k;Lb.len=j;}3、编写一个统计单循环链表的结点个数的算法。

解:int count(Lnode *L){ Lnode *p=L->next;int n=0;while(p!=L){ n++; p=p->next; }return n;}4、编写删除有序单链表中元素值大于min并且小于max的全部元素的算法。

如果给定的表是无序的,如何改写上面的算法。

解:void del4(Lnode *L,Elemtype min , Elemtype max ){ Lnode *q,*s,*p ;p=L->next; q=L;while (p!=NULL&&p->date<=min){ q=p; p=p->next; }if (p!=NULL)//表示存在大于min的结点,最后一个小于等于min的结点为q结点{while (p!=NULL&&p->date<max)p=p->next;if (p!=NULL)// 表示存在大于等于max的结点,既p结点while (q->next!=p) //删除q的后继结点到p的前驱结点为止的所有结点{ s=q->next; q->next=s->next; free(s); }else{ s=q->next; q->next=NULL;//q以后的结点全部要删除while (s!=NULL){ p=s->next; free(s); s=p; }}}5、用顺序表来求集合的并集、交集和差集,也可以用链表来实现以上操作。

(作为上机实践题目)# include < stdio.h >typedef int Elemtype ;# define maxlen 100# define N 30struct ListSq{Elemtype e [ maxlen ] ;int len ;};//顺序表的创建算法void Create_Sq( ListSq &L , Elemtype A[ ] , int n ) {int i ;for ( i=0 ; i<n ; i++ )L.e[i] =A[i];L.len=n ;}//顺序表的输出算法void PrintList( ListSq L ){printf("当前集合为:\n");for ( int i=0; i<L.len; i++)printf("%d\t" , L.e [ i ] ) ;printf ( "\n" ) ;}void bingji(ListSq L1,ListSq L2,ListSq &L3){for(int k=0;k<L1.len;k++)L3.e[k]=L1.e[k];L3.len=L1.len;for (int i=0;i<L2.len;i++){int j=0;while((j<L1.len)&&(L2.e[i]!=L1.e[j]))j++;if (j>=L1.len){L3.e[L3.len]=L2.e[i];L3.len++;}}}void jiaoji(ListSq L1,ListSq L2,ListSq &L3){int k=0;for(int i=0;i<L1.len;i++){int j=0;while((j<L2.len)&&(L1.e[i]!=L2.e[j])) j++;if(j<L2.len)L3.e[k++]=L1.e[i];}L3.len=k;}void chaji(ListSq L1,ListSq L2,ListSq &L3) {int k=0;for(int i=0;i<L1.len;i++){int j=0;while((j<L2.len)&&(L1.e[i]!=L2.e[j])) j++;if(j>=L2.len)L3.e[k++]=L1.e[i];}for(int m=0;m<L2.len;m++){int n=0;while((n<L1.len)&&(L2.e[m]!=L1.e[n])) n++;if(n>=L1.len)L3.e[k++]=L2.e[m];}L3.len=k;}//主函数void main ( ){ListSq L1,L2,L3 ;L3.len=0;int A[ N ];int m,n,c;printf("请输入线性表L1的元素个数:\n"); scanf("%d",&m);printf("请输入线性表L1的元素:\n");for ( int j=0; j<m; j++)scanf("%d",&A[ j ]) ;Create_Sq( L1 , A , m );PrintList( L1 ) ;printf("请输入线性表L2的元素个数:\n");scanf("%d",&n);printf("请输入线性表L2的元素:\n");for ( int w=0; w<n; w++)scanf("%d",&A[ w ]) ;Create_Sq( L2 , A , n );PrintList( L2 ) ;while(1){printf("请按提示进行输入:\n");printf("实现两个集合的并集,请输入1:\n");printf("实现两个集合的交集,请输入2:\n");printf("实现两个集合的差集,请输入3:\n");printf("退出,请输入4:\n");scanf("%d",&c);switch(c){case 1:{bingji(L1,L2,L3);PrintList( L3 ) ;break;}case 2:{jiaoji(L1,L2,L3);PrintList( L3 ) ;break;}case 3:{chaji(L1,L2,L3);PrintList( L3 );break;}case 4:return;default: printf("输入有误!\n");}}}6、用循环单链表来实现约瑟夫问题。

相关主题