12数据结构作业.docx
《12数据结构作业.docx》由会员分享,可在线阅读,更多相关《12数据结构作业.docx(50页珍藏版)》请在冰豆网上搜索。
12数据结构作业
数据结构
作业
第一章:
1.3设有数据结构(D,R),其中
D={d1,d2,d3,d4},R={r},r={(d1,d2),(d2,d3),(d3,d4)}.
是按图论中的画法惯例画出其逻辑结构图。
答:
1.4试仿照三元组的抽象数据类型分别写出抽象数据类型复数和有理数的定义(有理数是其分子、分母均为自然数且分母不为零的分数)。
a.抽象数据类型复数complex:
ADTcomplex{
数据对象:
D={e1,e2|e1,e2∈R}
数据关系:
R1={}
基本操作:
Initcomplex(&T,v1,v2)
操作结果:
构造了复数T,元素e1,e2分别被赋以参数v1,v2的值.
Destroycomplex(&T)
初始条件:
复数T已存在.
操作结果:
复数T被销毁.
Get(T,i,&e)
初始条件:
复数T已存在,1≤i≤2.
操作结果:
用e返回T的实部或虚部的值。
Isascending(T)
初始条件:
复数T已存在。
操作结果:
两部分按升序排列,则返回1,否则返回0.
Isdescending(T)
初始条件:
复数T已存在。
操作结果:
两部分按降序排列,则返回1,否则返回0.
Put(&T,I,e)
初始条件:
复数T已存在,1≤i≤2.
操作结果:
改变T实部或虚部的值为e.
Max(T,&e)
初始条件:
复数T已存在。
操作结果:
用e返回实部,虚部中较大的值。
Min(T,&e)
初始条件:
复数T已存在
操作结果:
用e返回实部,虚部中较小的值。
}ADTcomplex
b.抽象数据类型有理数:
ADTrational{
数据对象:
D={a,b|a,b为整数,且b不为0}
数据关系:
R={}
基本操作:
Initrational(&T,v1,v2)
操作结果:
构造有理数T,元素啊,a,b分别被赋以参数v1,v2的值。
Destroyrational(&T)
初始条件:
有理数T已存在。
操作结果:
有理数T被销毁。
Get(T,i,&e)
初始条件:
有理数T已存在,1≤i≤2.
操作结果:
用e返回T的分子或分母的值。
Put(&T,i,e)
初始条件:
有理数T已存在,1≤i≤2.
操作结果:
改变T的分子或分母的值为e.
Isascending(T)
初始条件:
复数T已存在。
操作结果:
两部分按升序排列,则返回1,否则返回0.
Isdescending(T)
初始条件:
复数T已存在。
操作结果:
两部分按降序排列,则返回1,否则返回0.
Max(T,&e)
初始条件:
有理数T已存在。
操作结果:
用e返回分子,母中较大一个的值。
Min(T,&e)
初始条件:
有理数T已存在。
操作结果:
用e返回分子,分母中较小的一个。
}ADTrational
1.8设n为正整数。
试确定下列各程序段中前置以记号@的语句的频度:
(1)i=1;k=0;
while(i<=n-1){
@k+=10*i;………………..
(1)
i++;……………....
(2)
}
频度:
n-1(因为语句
(1),
(2)总会一起执行,所以i的取值次数即为语句
(1)的频度)
(2)i=1;k=0;
do{
@k+=10*i;
i++;
}while(i<=n-1);
频度:
n-1(dowhile循环只在第一次循环上与其他循环结构不同)
(3)i=1;k=0;
while(i<=n-1){
i++;
@k+=10*i;
}
频度:
n-1(同样以i为判断标准)
(4)k=0;
for(i=1;i<=n;i++){
for(j=i;j<=n;j++)
@k++;
}
频度:
n(n+1)/2
(5)for(i=1;i<=n;i++){
for(j=1;j<=i;j++){
for(k=1;k<=j;k++)
@x+=delta;
}
频度:
n(n+1)(2n+3)/12(即为
(1)+(1+2)+(1+2+3)+(1+2+3+4)+...(1+2+...+n))
(6)i=1;j=0;
while(i+j<=n){
@if(i>j)j++;
elsei++;
}
频度:
n
(7)x=n;y=0;//n是不小于1的常数
while(x>=(y+1)*(y+1)){
@y++;
}
频度:
[√n]
(8)x=91;y=100;
while(y>0){
@if(x>100){x-=10;y--;}
elsex++;
}
频度:
1100次(x从91到101共10次,y减1一次,往复循环100次)
1.9假设n为2的乘幂,并且n>2,试求下列算法的时间复杂度及变量count的值(以n的函数形式表示)。
intTime(intn){
count=0;x=2;
while(xx*=2;count++;
}
returncount;
}
解:
T(n)=
count=
10.比较函数增长率:
(2/3)n,2100,
(
),
(
)2,
n2/3,n/
n,n
n3/2,(4/3)n,(3/2)n,n
n!
nn
1.18假设有A,B,C,D,E五个高等院校进行田径对抗赛,各院校的单项成绩均已存入计算机,并构成一张表,表中每一行的形式为
项目名称
性别
校名
成绩
得分
编写算法,处理上述表格,以统计各院校的男、女总分和团体总分,并输出。
解:
typedefenum{A,B,C,D,E}shoolname;
typedeyenum{male,female}sex;
tepedefstruct{
charevent[10];//项目
sexs;//性别
schoolnamen;//校名
intscore;//分数
}record;
typedefstruct{
intmalescore;//男生得分
intfemalescore;//女生得分
inttotalscore;//总得分
}sum;
sumcompute(schloolnamen,recorda[],intn)
{
sumterm;
term.malescore=0;
term.femalescore=0;
term.totalscore=0;
for(i=0;i<=n;i++){
if(a[i].schoolname==n){
if(a[i].sex==male)term.malescore++;
elseterm.femalescore++;
}
}
Term.totalscore=term.malescore+term.femalescore;
returnterm;//返回统计每个学校的得分情况的结构体
}
附加:
复数数据结构的实现:
#include
#include
#defineTURE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
#defineOVERFLOW-2
structcomplex{
floate1;
floate2;
};
structcomplex*Initcomplex(floatv1,floatv2)
{
structcomplex*T;
T=(structcomplex*)malloc(sizeof(structcomplex));
T->e1=v1;T->e2=v2;
printf("实数:
%f+i%f\n",T->e1,T->e2);
returnT;
}
intDestroycomplex(structcomplex*T)
{
free(T);T=NULL;
return1;
}
floatGet(structcomplex*T,inti)
{floate;
if(i<1||i>2)returnERROR;
if(i==1)e=T->e1;
elsee=T->e2;
returne;
}
intPut(structcomplex*T,inti,floate)
{
if(i<1||i>2)returnERROR;
if(i==1)T->e1=e;
elseT->e2=e;
returnOK;
}
intIsAscending(structcomplex*T)
{
return(T->e1<=T->e2);
}
intIsDescending(structcomplex*T)
{
return(T->e1>=T->e2);
}
floatMax(structcomplex*T)
{
floate;
e=(T->e1>T->e2)?
T->e1:
T->e2;
returne;
}
floatMin(structcomplex*T)
{
floate;
e=(T->e1e2)?
T->e1:
T->e2;
returne;
}
voidmain()
{
inti;
floatv1,v2,e;
structcomplex*a;
printf("实部,虚部\n");
scanf("%f,%f",&v1,&v2);
a=Initcomplex(v1,v2);
printf("更改实部:
1,更改虚部:
2\n");
scanf("%d",&i);
printf("更改后的值为:
");
scanf("%f",&e);
if(Put(a,i,e))
printf("改后复数:
%f+i%f\n",a->e1,a->e2);
if(Destroycomplex(a))printf("复数已销毁");
printf("改后复数:
\n%f+i%f\n",a->e1,a->e2);
}
操作结果:
第二章:
习题3:
2.11设顺序表va中的数据元素递增有序。
试写一算法,将x插入到顺序表的适当位置上,以保持该表的有序性。
解:
程序源代码:
#include
#include
#defineLIST_INTT_SIZE100
#defineLISTINCREMENT10
typedefstruct{
int*elem;
intlength;
intsize;
}list;
voidmain()
{
listlist1;
inti,e,n;
printf("请输入顺序表数据元素个数:
\n");
scanf("%d",&n);
list1.elem=(int*)malloc(LIST_INTT_SIZE*sizeof(int));
if(list1.elem){list1.length=0;list1.size=LIST_INTT_SIZE;}
i=1;
while(i<=n){
if(list1.length>=list1.size-1){
list1.elem=(int*)realloc(list1.elem,(list1.size+LISTINCREMENT));
list1.size+=LISTINCREMENT;}
printf("\n请输入第%d个数据元素值:
",i);
scanf("%d",&e);
list1.elem[i-1]=e;
i++;
list1.length++;
}
printf("输入的顺序表为:
\n");
i=1;
while(i<=n)
{
printf("%d",list1.elem[i-1]);
i++;
}
printf("\n请输入要插入的数据元素:
\n");
scanf("%d",&e);
for(i=list1.length;i>0&&elist1.elem[i]=list1.elem[i-1];
list1.elem[i]=e;
list1.length++;
printf("输入的顺序表为:
\n");
i=1;
while(i<=list1.length)
{
printf("%d",list1.elem[i-1]);
i++;
}
}
运行结果:
2.12设
和
均为顺序表,
和
分别为
和
中除去最大共同前缀后的子表。
若
空表,则
;若
=空表,而
空表,或者两者均不为空表,且
的首元小于
的首元,则
;否则
。
试写一个比较
,
大小的算法。
解:
程序源代码:
#include
#include
#defineLIST_INTT_SIZE100
#defineLISTINCREMENT10
typedefstruct{
int*elem;
intlength;
intsize;
}list;
voidmain()
{
listlist1,list2;
inti,e,n1,n2;
printf("请输入顺序表A数据元素个数:
\n");
scanf("%d",&n1);
list1.elem=(int*)malloc(LIST_INTT_SIZE*sizeof(int));
if(list1.elem){list1.length=0;list1.size=LIST_INTT_SIZE;}
i=1;
printf("请输入顺序表A各数据元素:
\n");
while(i<=n1){
if(list1.length>=list1.size-1){
list1.elem=(int*)realloc(list1.elem,(list1.size+LISTINCREMENT));
list1.size+=LISTINCREMENT;}
scanf("%d",&e);
list1.elem[i-1]=e;
i++;
list1.length++;
}
printf("输入的A顺序表为:
\n");
i=1;
while(i<=n1)
{
printf("%d",list1.elem[i-1]);
i++;
}
printf("\n请输入顺序表B数据元素个数:
\n");
scanf("%d",&n2);
list2.elem=(int*)malloc(LIST_INTT_SIZE*sizeof(int));
if(list2.elem){list2.length=0;list2.size=LIST_INTT_SIZE;}
i=1;
printf("请输入顺序表B各数据元素:
\n");
while(i<=n2){
if(list2.length>=list2.size-1){
list2.elem=(int*)realloc(list2.elem,(list2.size+LISTINCREMENT));
list2.size+=LISTINCREMENT;}
scanf("%d",&e);
list2.elem[i-1]=e;
i++;
list2.length++;
}
printf("输入的B顺序表为:
\n");
i=1;
while(i<=n2)
{
printf("%d",list2.elem[i-1]);
i++;
}
if(!
list1.elem)
if(!
list2.elem)printf("\n比较结果为:
A=B\n");
elseprintf("\n比较结果为:
A
if(list1.elem)if(!
list2.elem)printf("\n比较结果为:
A>B\n");
if(list1.elem&&list2.elem){
for(n1=0,n2=0;(list1.elem[n1]&&list2.elem[n2])&&list1.elem[n1]==list2.elem[n2];n1++,n2++){}
if(!
list1.elem[n1])
if(!
list2.elem[n2])printf("\n比较结果为:
A=B\n");
elseprintf("\n比较结果为:
A>B\n");
if(list1.elem)if(!
list2.elem)printf("\n比较结果为:
A
if(list1.elem[n1]>list2.elem[n2])printf("\n比较结果为:
A>B\n");
if(list1.elem[n1]A
}
}
运行结果:
2.21试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将线性表
逆置为
。
解:
程序源代码:
#include
#include
#defineLIST_INTT_SIZE100
#defineLISTINCREMENT10
typedefstruct{
int*elem;
intlength;
intsize;
}list;
voidmain()
{
listlist1;
inti,e,n;
printf("请输入顺序表数据元素个数:
\n");
scanf("%d",&n);
list1.elem=(int*)malloc(LIST_INTT_SIZE*sizeof(int));
if(list1.elem){list1.length=0;list1.size=LIST_INTT_SIZE;}
i=1;
printf("请输入顺序表各数据元素:
\n");
while(i<=n){
if(list1.length>=list1.size-1){
list1.elem=(int*)realloc(list1.elem,(list1.size+LISTINCREMENT));
list1.size+=LISTINCREMENT;}
scanf("%d",&e);
list1.elem[i-1]=e;
i++;
list1.length++;
}
printf("输入的顺序表为:
\n");
i=1;
while(i<=n)
{
printf("%d",list1.elem[i-1]);
i++;
}
for(i=0,n=list1.length-1;i<=n;i++,n--)
{
e=list1.elem[i];
list1.elem[i]=list1.elem[n];
list1.elem[n]=e;
}
printf("\n逆转后的的顺序表为:
\n");
i=1;n=list1.length;
while(i<=n)
{
printf("%d",list1.elem[i-1]);
i++;
}
printf("\n");
}
运行结果:
2.15已知指针ha和hb分别指向两个单链表的头结点,并且已知两个链表的长度分别为m和n。
试写一算法将这两个链表连接在一起,假设指针hc指向连接后的链表的头结点,并要求算法以尽可能短的时间完成连接运算。
请分析你的算法的时间复杂度。
解:
程序源代码:
#include
#include
typedefstructlnode{
intdata;
structlnode*next;
}list,*linklist;
voidmain()
{
inti,m,n;
linklistha,hb,hc,p1,p2;
ha=(linklist)malloc(sizeof(structlnode));
ha->next=NULL;
p1=ha;
hb=(linklist)malloc(sizeof(structlnode));
hb->next=NULL;
p2=hb;
printf("请输入链表1长度:
\n");
scanf("%d",&m);
printf("请输入链表1:
\n");
for(i=1;i<=m;i++)
{
p1->next=(linklist)malloc(sizeof(structlnode));
scanf("%d",&p1->next->data);
p1=p1->next;
p1->next=NULL;
}
printf("请输入链表2长度:
\n");
scanf("%d",&n);
printf("请输入链表2:
\n");
for(i=1;i<=n;i++)
{
p2->next=(linklist)malloc(sizeof(structlnode));
scanf("%d",&p2->next->data);
p2=p2->next;
p2->next=NULL;
}
if(m<=n)
{
for(p1=ha;p1->next!
=NULL;p1=p1->next){}
p1->next=hb->next;
hc=(linklist)malloc(sizeof(structlnode));
hc->next=ha->next;
}
if(m>n)
{
for(p2=hb;p2->next!
=NULL;p2=p2->next){}
p2->next=ha->next;
hc=(linklist)malloc(sizeof(structlnode));
hc->next=hb->next;
}
free(ha);free(hb);
printf("连接后链表为\n");
for(p1=hc;p1->next!
=NULL;p1=p1->next)printf("%d",p1->next->data);
}
运行结果: