数据结构教程习题答案 李蓉蓉 安杨等编著第三版 第五章答案.docx
《数据结构教程习题答案 李蓉蓉 安杨等编著第三版 第五章答案.docx》由会员分享,可在线阅读,更多相关《数据结构教程习题答案 李蓉蓉 安杨等编著第三版 第五章答案.docx(23页珍藏版)》请在冰豆网上搜索。
数据结构教程习题答案李蓉蓉安杨等编著第三版第五章答案
5.3
/************************************
题目:
设有三对角矩阵A,将其三对角线上元素逐行存于数组B中求:
1:
用i,j表示k的下标变换公式
k=2*i+j(下标从0开始)
2:
用k表示i,j的下标公式(下标从0开始)
i=(k+1)/3:
(此处取整)
j=k-2*i;
=k-(k+1)/3*2(此处别化简)
什么是三对角矩阵?
在线性代数中,一个三对角矩阵是矩阵的一种,
它“几乎”是一个对角矩阵。
准确来说:
一个三对角矩阵的非零系数在主对角线上,
或比主对角线低一行的对角线上,或比主对角线高一行的对角线上。
例如,下面的是三对角矩阵:
1400
3410
0234
0013
**************************************************************************/
/*****************下面是具体的实现*************/
#include
#definesize50
//函数的声明
voidtranslate(int*b,inta[size][size],intn);
main()
{
intn;
inti,j,k=0;
inta[size][size];
intb[size];
printf("输入矩阵的阶数\n");
scanf("%d",&n);
printf("输入%d个数据\n",2*(n-1)+(n-1)+1);//2*(n-1)+(n-1)+1的来历是由上面的公式(2*i+j)推来
//三对角矩阵的最后一个元素一定在(n-1,n-1)位置,既然
//一维组的下标与i,j有关,那么k最大也会在i=n-1,j=n-1处
//一维数组的下标k随着i,j连续增加的
//往三对角矩阵中输入数据
while(k<2*(n-1)+(n-1)+1)
{
for(i=0;i{
for(j=0;j{
if((i==(k+1)/3)&&(j==k-(k+1)/3*2))
{
scanf("%d",&a[i][j]);
k++;
}
else
a[i][j]=0;
}
}
}
printf("你输入的三对角矩是\n");
for(i=0;i{
for(j=0;jprintf("%d",a[i][j]);
printf("\n");
}
//将三对角矩阵中的元素输入到一位数组b中
translate(b,a,n);
printf("压缩后的结果\n");
for(i=0;i<2*(n-1)+(n-1)+1;i++)
printf("%d",b[i]);
printf("\n");
}
//进行压缩
voidtranslate(int*b,inta[size][size],intn)
{
inti,j,k=0;
while(k<2*(n-1)+(n-1)+1)
{
for(i=0;i{
for(j=0;j{
if(k==2*i+j&&0!
=a[i][j])
b[k++]=a[i][j];
}
}
}
}
/**********************************************
输入矩阵的阶数
4
输入10个数据
1234567893
你输入的三对角矩是
1200
3450
0678
0093
压缩后的结果
1234567893
Pressanykeytocontinue
*******************************************************/
5.5
/******************************************
题目:
设定二维整数数组B[0...m-1,0...n-1]的数据在行列上都按从小到大的顺序排序,
且整型变量x中的数据在B中存在。
试设计一个算法
找出一对满足B[i][j]=i,j值,要求比较次数不超过m+n
设计;狼影
时间:
2012.9.30
***************************************************************/
/**************************************
!
!
下面是自己的看法,若有不对之处(或有更好的方式),请留言本空间,万分感谢
既然有序,就要好好利用一下喽,,首先想到的就是二分查找,那怎么个二分法呢?
我的方法是将二维当做一维用。
时间复杂度是O(log2(m*n))=O(log2m+log2n)********************************************************************************************/
#include
inti=-1,j=-1;
//函数声明
voidprint_arry(inta[5][5]);
voidfind_x(inta[5][5],intx);
main()
{
intx;
inta[5][5]={{1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15},
{16,17,18,19,20},
{21,22,23,24,25}
};
print_arry(a);
printf("输入要查找的数\n");
scanf("%d",&x);
//在数组中寻找x
find_x(a,x);
if(-1==i||-1==j)
printf("没有要查找的数据\n");
else
printf("x的位置是(%d,%d)\n",i,j);
}
//输出数组中的内容
voidprint_arry(inta[5][5])
{
inti,j;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
printf("%2d",a[i][j]);
}
printf("\n");
}
}
//寻找x的位置
voidfind_x(inta[5][5],intx)
{
intmid;
intx1=0,y1=24;
while(x1<=y1)
{
mid=(x1+y1)/2;
if(x==a[0][mid])
{
i=mid/5;
j=mid%5;
return;
}
elseif(x>a[0][mid])
x1=mid+1;
else
y1=mid-1;
}
}
/*****************************************
12345
678910
1112131415
1617181920
2122232425
输入要查找的数
21
x的位置是(4,0)
Pressanykeytocontinue
*********************************************/
5.6
/**********************
题目:
编写一个算法,计算一个三元组表示的稀疏矩阵的对角线之和
设计:
狼影
时间:
2012.9.28
*************************************/
/*********************************
这里求的是行和列相等的矩阵对角线元素和,,如果你会行和列不相等的矩阵对角线元素法,告诉一声啊,万分感激(不用三元组页可以哦!
)
*********************/
#include
#definesize100
typedefstruct
{
intx;//存放某一个非零元的行
inty;//存放某一个非零元的列
intdata;//存放某一个非零元
}DATA;
typedefstruct
{
introw;//存储矩阵的总行数
intcol;//存储矩阵的总列数
intnumber;//存储非零元的个数
DATAarry[size];//三元组数组
}NODE;
//函数的声明
voidreduce(inta[size][size],NODE*MA,intn);
voidprint_arry(NODEMA);
intcal_sum(NODEMA,intn);
main()
{
intn;
NODEMA;
inti,j;
intsum=0;
inta[size][size];
printf("输入矩阵的阶数\n");
scanf("%d",&n);
//对矩阵进行赋值
printf("输入矩阵元素\n");
for(i=0;i{
for(j=0;j{
scanf("%d",&a[i][j]);
}
}
//对矩阵进行压缩
reduce(a,&MA,n);
print_arry(MA);
//求对角线的和
sum=cal_sum(MA,n);
printf("对角线的和是%d\n",sum);
}
//矩阵的压缩
voidreduce(inta[size][size],NODE*MA,intn)
{
inti,j;
MA->col=n;
MA->row=n;
MA->number=0;
for(i=0;i{
for(j=0;j{
if(0!
=a[i][j])
{
MA->arry[MA->number].x=i;
MA->arry[MA->number].y=j;
MA->arry[MA->number].data=a[i][j];
MA->number++;
}
}
}
}
//打印压缩矩阵
voidprint_arry(NODEMA)
{
inti;
if(0==MA.number)
{
printf("三元组空\n");
return;
}
for(i=0;i{
printf("(%d,%d)**%d\n",MA.arry[i].x,MA.arry[i].y,MA.arry[i].data);
}
}
//求对角线的和
intcal_sum(NODEMA,intn)
{
intsum=0;
inti;
if(0==MA.number);
else
{
for(i=0;i{
if(MA.arry[i].y==MA.arry[i].x||(n-1)==(MA.arry[i].x+MA.arry[i].y))//是矩阵对角线的条件
{
sum+=MA.arry[i].data;
}
}
}
returnsum;
}
/*********************************
输入矩阵的阶数
3
输入矩阵元素
123
456
040
(0,0)**1
(0,1)**2
(0,2)**3
(1,0)**4
(1,1)**5
(1,2)**6
(2,1)**4
对角线的和是9
Pressanykeytocontinue
**********************************************/
5.8
/*****************************************
题目:
设计一个算法same(*h1,*h2)判断两个广义表相同
设计;狼影
时间:
2012.9.29
*****************************************/
/**********************************************************
此算法根据线性表推倒而出,若测试有不对之处,请留言本人空间,你的留言将是对本人学习的最大帮助,万分感谢
************************************************************************************************************/
#include
#include
#include
#definesize100
//节点的定义
typedefstructnode
{
inttag;//标记
union
{
chardata;
structnode*sublist;
}VALUE;
structnode*pNext;
}NODE;
//函数的声明
NODE*new_node(void);
NODE*creat(void);
voidoutput(NODE*p);
intsame(NODE*p1,NODE*p2);
char*s;
main()
{
NODE*h1;
NODE*h2;
intn;
chars1[size];
chars2[size];
//输入广义表的内容
printf("输入广义表1内容,格式为(a,(b,c))\n");
gets(s1);
fflush(stdin);
printf("输入广义表2内容,格式为(a,(b,c),(a,f))\n");
gets(s2);
//构造广义表
s=s1;
h1=creat();
s=s2;
h2=creat();
printf("输出广义表的内容是\n");
//输出广义表(此处只是对广义表的输出,如果只是向完成题目要求并且嫌麻烦,接下来的四句可以省略)
output(h1);
printf("\n");
output(h2);
printf("\n");
//***************************************************
n=same(h1->VALUE.sublist,h2->VALUE.sublist);
if(0==n)
printf("两广义表不相等\n");
else
printf("两个广义表相等\n");
}
//建立广义表
NODE*creat()
{
charch;
NODE*pNew;
ch=*s++;
if(ch!
='\0')
{
pNew=new_node();
if('('==ch)
{
pNew->tag=1;//1标记子表
pNew->VALUE.sublist=creat();//递归的建立子表
}
elseif(')'==ch)
{
pNew=NULL;
}
else
{
pNew->tag=0;//0标记原子
pNew->VALUE.data=ch;
}
}
else
pNew=NULL;
if(pNew!
=NULL)
{
ch=*s++;
if(','==ch)
pNew->pNext=creat();//建立兄弟表
else
pNew->pNext=NULL;
}
returnpNew;
}
//创建新的节点
NODE*new_node(void)
{
NODE*pNew;
pNew=(NODE*)malloc(sizeof(NODE));
if(NULL==pNew)
{
printf("内存分配错误\n");
exit(-1);
}
pNew->pNext=NULL;
returnpNew;
}
//输出广义表的内容
voidoutput(NODE*p)
{
if(NULL!
=p)
{
if(1==p->tag)
{
printf("(");
if(NULL==p->VALUE.sublist)
printf("");
else
output(p->VALUE.sublist);
}
else
{
printf("%c",p->VALUE.data);
}
if(1==p->tag)
printf(")");
if(p->pNext!
=NULL)
{
printf(",");
output(p->pNext);
}
}
}
//判断两个广义表是否相等
intsame(NODE*p1,NODE*p2)
{
intn=0;
if(NULL==p1&&NULL==p2)
n=1;
elseif(NULL!
=p1&&NULL==p2||NULL==p1&&NULL!
=p2)
n=0;
else
{
if(1==p1->tag&&1==p2->tag)
n=(same(p1->VALUE.sublist,p2->VALUE.sublist)&&same(p1->pNext,p2->pNext));
if(0==p1->tag&&0==p2->tag&&p1->VALUE.data==p2->VALUE.data)
{
n=1;
n=same(p1->pNext,p2->pNext);
}
}
returnn;
}
/**********************************************
输入广义表1内容,格式为(a,(b,c))
((a,f),(),(),(),b,f)
输入广义表2内容,格式为(a,(b,c),(a,f))
((a,f),(),(),())
输出广义表的内容是
((a,f),(),(),(),b,f)
((a,f),(),(),())
两广义表不相等
Pressanykeytocontinue
************************************************************************/
/*************************************
下面是两个链表比较是否相同的递归方法,根据它,来写广义表的比较方法(从某种意义说,广义表也是线性表,它有着和线性表相同的的性质)
很多基本算法都可以根据线性表来推出广义表的算法********************(仅供参考)
*************************/
/******************************************
typedefstructnode
{
intdata;
structnode*pNext;
}NODE;
//函数的声明
NODE*init_list(void);
voidcreat_list(NODE*pHead,intn);
intsame(NODE*p1,NODE*p2);
main()
{
NODE*pHead1,*pHead2;
ints;
intn,m;
pHead1=init_list();
pHead2=init_list();
printf("输入第一个链表的个数\n");
scanf("%d",&n);
creat_list(pHead1,n);
printf("输入第二个链表的个数\n");
scanf("%d",&m);
creat_list(pHead2,m);
s=same(pHead1->pNext,pHead2->pNext);
if(1==s)
printf("相等\n");
else
printf("不相等\n");
}
//初始化头节点
NODE*init_list(void)
{
NODE*pHead=(NODE*)malloc(sizeof(NODE));
if(NULL==pHead)
{
printf("内存分配失败\n");
exit(-1);
}
pHead->pNext=NULL;
returnpHead;
}
//创建链表
voidcreat_list(NODE*pHead,intn)
{
inti;
NODE*pNow=pHead,*pNew;
printf("输入%d个数据\n",n);
for(i=0;i{
pNew=(NODE*)malloc(sizeof(NODE));
if(NULL==pNew)
{
printf("内存分配失败\n");
exit(-1);
}
pNew->pNext=NULL;
scanf(