线性链表的实现及操作汇总.docx
《线性链表的实现及操作汇总.docx》由会员分享,可在线阅读,更多相关《线性链表的实现及操作汇总.docx(21页珍藏版)》请在冰豆网上搜索。
线性链表的实现及操作汇总
数据结构【第七次】实验报告
学院:
班级:
学号:
姓名:
实验七
(一)实验名称:
线性链表的实现及操作
(二)实验目的:
1)深入理解线性链表的逻辑结构和链式存储结构;
2)掌握线性链表的基本操作及应用:
3)培养学生灵活使用结构解决实际问题的能力。
(三)实验要求:
1)设计一个100位以内的长整数加减运算的程序。
要求如下:
输入输出要求:
每四位一组,组间用逗号分隔;
加和减分别用不同的程序实现
程序应考虑输入数据的符号
2)用循环链表实现约瑟夫环问题
(四)源代码:
1)100位以内的长整数加减运算的源代码:
#include
#include
#defineLENsizeof(Number)
typedefstructnumberNumber;
structnumber
{
intdata;
Number*next;
Number*prior;
};
voidmain()
{
voidDestoryList(Number*);//释放链表
voidPutNumber(Number*);//将求得的结果输出
Number*GetNumber();//创建链表,放被加数与加数
Number*JiaFa(Number*num_1,Number*num_2);//加法函数
Number*JianFa(Number*num_1,Number*num_2);//减法函数
Number*number_1,*number_2,*number;
charch;//存放运算符号
printf("Enterthefirstlongnumber:
");
number_1=GetNumber();
printf("put+or-:
");
ch=getchar();
fflush(stdin);//吸收不相关的字符
printf("Enterthesecondlongnumber:
");
number_2=GetNumber();
if(ch=='+')
number=JiaFa(number_1,number_2);
else
if(ch=='-')
number=JianFa(number_1,number_2);
printf("\n=\n");
PutNumber(number);
DestoryList(number);
DestoryList(number_1);
DestoryList(number_2);
printf("链表释放完成。
\n");
}
Number*GetNumber()//得到两个链表
{
Number*p,*q,*List;
charch;
p=(Number*)malloc(LEN);
List=p;
List->prior=NULL;
List->data=0;//加法时,放最高位进的1,否者999+1=000
ch=getchar();
while(ch!
='\n')
{
if(ch>='0'&&ch<='9')//过滤非数字字符
{
q=(Number*)malloc(LEN);
q->data=ch-'0';
p->next=q;
q->prior=p;
p=q;
}
ch=getchar();
}
p->next=NULL;
List->prior=NULL;
returnList;
}//加法分两种情况长度相同与不同
Number*JiaFa(Number*num_1,Number*num_2)//返回的数据为逆序
{
Number*p,*q,*r,*s,*num=NULL;
inti=0,j=0;
r=num;
p=num_1;
while(p->next!
=NULL)
{
i++;
p=p->next;
}//i表示number1数字的长度p指向number节点
q=num_2;
while(q->next!
=NULL)
{
j++;
q=q->next;
}//j表示number2数字的长度q指向number节点
s=(Number*)malloc(LEN);
s->prior=NULL;
s->next=NULL;
num=s;
while(i--&&j--)
{
s->data=p->data+q->data;
if(s->data>9)
{
s->data-=10;//**处理两数相加大于9的情况,后面还有
if(i>j)//在长的数据上调整
p->prior->data++;
else
q->prior->data++;
}
r=(Number*)malloc(LEN);
s->next=r;
r->prior=s;
s=r;
p=p->prior;
q=q->prior;
}
r=s=s->prior;//去掉最后一个没数据的节点
free(s->next);
s->next=NULL;
if(i>j)
{
while(i--)
{
if(p->data>9)
{
p->data-=10;//**
p->prior->data++;
}
s=(Number*)malloc(LEN);
s->data=p->data;
p=p->prior;
r->next=s;
s->prior=r;
r=s;
}
if(p->data>0)//**
{
s=(Number*)malloc(LEN);
s->data=p->data;
r->next=s;
s->prior=r;
r=s;
}
}
else
{
while(j--)
{
if(q->data>9)//**
{
q->data-=10;
q->prior->data++;
}
s=(Number*)malloc(LEN);
s->data=q->data;
q=q->prior;
r->next=s;
s->prior=r;
r=s;
}
if(q->data>0)//**
{
s=(Number*)malloc(LEN);
s->data=q->data;
r->next=s;
s->prior=r;
r=s;
}
}
s->next=NULL;//将最后一个next置空
returnnum;
}//减法分3中情况:
被减数长度大于、小于、等于减数长度
Number*JianFa(Number*num_1,Number*num_2)//返回的数据也为逆序
{
Number*p,*q,*r,*s,*num=NULL;
inti=0,j=0;
r=num;
p=num_1;
while(p->next!
=NULL)//i表示number1数字的长度p指向number节点
{
i++;
p=p->next;
}
q=num_2;
while(q->next!
=NULL)//j表示number2数字的长度q指向number节点
{
j++;
q=q->next;
}
s=(Number*)malloc(LEN);
s->prior=NULL;
s->next=NULL;
num=s;
if(i{
while(i--)
{
s->data=q->data-p->data;
if(s->data<0)//**
{
s->data+=10;
q->prior->data--;
}
r=(Number*)malloc(LEN);
s->next=r;
r->prior=s;
s=r;
p=p->prior;
q=q->prior;
j--;//使i,j同时变化
}
r=s=s->prior;//去掉最后一个没数据的节点
free(s->next);
s->next=NULL;
while(j--)
{
if(q->data<0)//**
{
q->data+=10;
q->prior->data--;
}
s=(Number*)malloc(LEN);
s->data=q->data;
q=q->prior;
r->next=s;
s->prior=r;
r=s;
}
s->data=0-s->data;//反号,因为节点里不能放符号,而直接在最高位前加负号最简单
s->next=NULL;
}
else
if(i==j)
{
i=j=1;
p=num_1;q=num_2;
while(p->data==q->data)
{
p=p->next;
q=q->next;
}
num_1=(Number*)malloc(LEN);
num_1->prior=NULL;
num_1->data=0;
num_1->next=p;
num_2=(Number*)malloc(LEN);
num_2->prior=NULL;
num_2->data=0;
num_2->next=q;
while(p->next!
=NULL)//i表示number1数字的长度p指向number节点
{
i++;
p=p->next;
}
q=num_2;
while(q->next!
=NULL)//j表示number2数字的长度q指向number节点
{
j++;
q=q->next;
}
if(num_1->next->data>num_2->next->data)
{
while(i--)
{
s->data=p->data-q->data;
if(s->data<0)//**
{
s->data+=10;
p->prior->data--;
}
r=(Number*)malloc(LEN);
s->next=r;
r->prior=s;
s=r;
p=p->prior;
q=q->prior;
}
r=s=s->prior;//去掉最后一个没数据的节点
free(s->next);
while(s->data==0&&s->prior!
=NULL)//去掉前面多余的0,否则111112-111111=000001
{
s=s->prior;
free(s->next);
}
}
if(num_1->next->datanext->data)
{
while(i--)
{
s->data=q->data-p->data;
if(s->data<0)//**
{
s->data+=10;
q->prior->data--;
}
r=(Number*)malloc(LEN);
s->next=r;
r->prior=s;
s=r;
p=p->prior;
q=q->prior;
}
r=s=s->prior;//去掉最后一个没数据的节点
free(s->next);
while(s->data==0&&s->prior!
=NULL)//去掉前面多余的0,否则111112-111111=000001
{
s=s->prior;
free(s->next);
}
}
s->data=0-s->data;//反号,因为节点里不能放符号,而直接在最高位前加负号最简单
s->next=NULL;
}
else
if(i>j)
{
while(j--)
{
s->data=p->data-q->data;
if(s->data<0)//**
{
s->data+=10;
p->prior->data--;
}
r=(Number*)malloc(LEN);
s->next=r;
r->prior=s;
s=r;
p=p->prior;
q=q->prior;
i--;
}
r=s=s->prior;//去掉最后一个没数据的节点
free(s->next);
s->next=NULL;
while(i--)
{
if(p->data<0)//**
{
p->data+=10;
p->prior->data--;
}
s=(Number*)malloc(LEN);
s->data=p->data;
p=p->prior;
r->next=s;
s->prior=r;
r=s;
}
while(s->data==0&&s->prior!
=NULL)//去掉前面多余的0,否则1000-1=0999
{
s=s->prior;
free(s->next);
}
//s->data=0-s->data;//反号,因为节点里不能放符号,而直接在最高位前加负号最简单
s->next=NULL;
}
returnnum;
}
voidPutNumber(Number*num)//链表的合并
{
Number*p;
intk=1,i;//k为数据长度,i控制‘,’
p=num;
while(p->next!
=NULL)
{
p=p->next;
k++;
}
i=4-k%4;
while(k--)
{
i++;
printf("%d",p->data);
p=p->prior;
if(k!
=0&&i%4==0)//长度为k的数据,在k%4个数字后开始输出‘,’数据输出完后不输出‘,’
putchar(',');
}
putchar('\n');
}
voidDestoryList(Number*list)//销毁链表
{
Number*p,*q;
p=list;
while(p)
{
q=p->next;
free(p);
p=q;
}
}
2)用循环链表实现约瑟夫环问题的源代码:
#include
#include
structLnode
{intnumber;
intpassword;
structLnode*next;
}Lnode,*p,*q,*head;
intmain(void)
{intn;
inti;
intm;
intj;
printf("pleaseenterthenumberofpeoplen:
");
scanf("%d",&n);
loop:
if(n<=0||n>30)
{printf("\nniserorr!
\n\n");
printf("pleaseenterthenumberofpeopleagainn:
");
scanf("%d",&n);
gotoloop;
}
for(i=1;i<=n;i++)
{if(i==1)
{head=p=(structLnode*)malloc(sizeof(structLnode));
}
else
{q=(structLnode*)malloc(sizeof(structLnode));
p->next=q;
p=q;
}
printf("pleaseenterthe%dpeople'spassword:
",i);
scanf("%d",&(p->password));
p->number=i;
}
p->next=head;
p=head;
printf("pleaseenterthenumberm:
");
scanf("%d",&m);
printf("Thepasswordis:
\n");
for(j=1;j<=n;j++)
{for(i=1;inext);
m=p->password;
printf("%d",p->number);
p->number=p->next->number;
p->password=p->next->password;
q=p->next;
p->next=p->next->next;
free(q);
}
printf("\n\n");
system("pause");
}
(五)运行结果:
1)100位以内的长整数加减运算的程序运行结果:
2)用循环链表实现约瑟夫环问题的程序运行结果:
(六)需求分析
1、输入的形式和输出值的范围:
1)每四位整数(0到9)一组,组间用逗号分隔;不超过100位的长整数。
2)输入人数n和每个人依次对应的编号1,2,3,4,5,、、、,n;所以人的编号。
2、输出的形式:
1)每四位一组,组间用逗号分隔。
2)输出所以人编号的出列顺序。
3、程序所能达到的功能:
1)一百位以内的长整数之间的加减法运算。
2)解答约瑟夫环问题。
(七)用到的函数或结构体:
1)100位以内的长整数加减运算的源代码:
typedefstruct
voidmain()
voidDestoryList()
voidPutNumber()
Printf()
2)用循环链表实现约瑟夫环问题的源代码:
structLnode
Voidmain()
Printf()
Scanf()
(八)心得体会:
通过此次实验,我更加深入的理解了线性链表的逻辑结构和链式存储结构。
认识并掌握了线性链表的基本操作及应用:
同时,加强了我用已有知识解决实际问题的能力,让我更有信心去学好即将面临的新知识。