实验二 线性链表
实验目的:
- 掌握线性表链式存储结构的定义方法;
- 掌握单链表、循环链表、双向链表各种基本操作的实现方法。
实验内容:
-
实现单链表类型,为其设计演示系统展示其基本操作。
实现要求:
1)单链表带头结点,元素为整型,基本操作包括:初始化、创建、遍历、读取第i个元素、插入、删除、求长度、清空、销毁;
2)主程序用于验证各基本操作的正确性;
3)主程序以用户和计算机对话的方式执行,实现过程为:
• 在主程序中初始化单链表;
• 主程序循环给出命令供用户选择,包括r(创建)、t(遍历)、g(读取第i个元素)、i(插入)、d(删除)、l(求长度)、c(清空)、 x(退出程序);
• 当用户输入命令后,系统根据用户命令提示用户输入数据信息,主程序调用相应函数执行操作并反馈给用户相关信息;
• 直至用户输入退出命令,销毁单链表。
4)注意:基本操作间的约束关系,例如:单链表初始化后才可以执行创建操作;创建操作必须在单链表为空的前提下才可以执行,否则会导致内存泄露,因此再次执行创建操作前必须有清空操作。 -
约瑟夫环问题:编号为1,2,…,n的人顺时针围坐一圈,每人持一密码。一开始任取一正整数m作为报数上限,从第1个人开始报数,报至m的人出列,并以其密码作为新的m,他在顺时针方向的下一个人重新开始从1报数,如此下去,直至所有人出列。求出列顺序。
实现要求:
1) 根据实际问题需要合理设计存储结构;
2) 程序实现过程为:
• 用户输入人数n及报数上限初始值m;
• 提示用户输入各人所持的密码;
• 程序处理完毕输出结果。
第一题代码
#include<bits/stdc++.h>
#define size 100
using namespace std;
typedef struct lnode
{
int data;
struct lnode *next;
}*link,lnode;
int check(char a)
{
char s[size]="rtgidlc";
int i;
for(i=0;i<strlen(s);i++)
{
if(s[i]==a)
return 1;
}
return 0;
}
void print()
{
cout<<endl<<"r(创建)、t(遍历)、g(读取第i个元素)、i(插入)"<<endl;
cout<<"d(删除)、l(求长度)、c(清空)、 x(退出程序)"<<endl;
}
void init(lnode *&l) //初始化
{
l=(lnode *)malloc(sizeof(lnode));
l->next=NULL; //链表带头结点; 不带头节点:l=NULL
}
void creat(lnode *&l) //创建链表
{
int i,n,t;
init(l);
lnode *p=l,*q;
cout<<"输入链表元素的个数"<<endl;
cin>>n;
cout<<"输入元素:";
for(i=0;i<n;i++)
{
q=(lnode *)malloc(sizeof(lnode));
cin>>t;
q->data=t;
p->next=q;
p=q;
}
p->next=NULL;
cout<<"创建成功!"<<endl;
}
void trace(lnode *l)
{
link p=l->next;
if(p)
{
cout<<"元素为:";
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
else
cout<<"链表为空"<<endl;
}
void getdata(lnode *l)
{
int i,n;
lnode *p=l->next;
cout<<"输入查找的位置:"<<endl;
cin>>n;
for(i=0;i<n-1;i++)
p=p->next;
if(p)
{
cout<<"元素为:"<<p->data<<endl;
}
else
cout<<"位置越界!"<<endl;
}
void insert(lnode *&l)
{
int i,n,t;
lnode *q=l,*r;
cout<<"输入插入的位置:"<<endl;
cin>>n;
cout<<"输入插入的元素:"<<endl;
cin>>t;
r=(lnode *)malloc(sizeof(lnode));
r->data=t;
r->next=NULL;
for(i=0;i<n-1;i++)
{
q=q->next;
}
if(q)
{
r->next=q->next;
q->next=r;
}
else
cout<<"位置越界!"<<endl;
}
void del(lnode *&l)
{
int i,n;
lnode *p,*q=l;
cout<<"输入要删除的位置:";
cin>>n;
for(i=0;i<n-1;i++)
{
q=q->next;
}
if(q)
{
p=q->next;
q->next=q->next->next;
free(p);
cout<<"删除成功!"<<endl;
}
else
cout<<"位置越界!"<<endl;
}
void getlength(lnode *l) //获取链表长度
{
int llength=0;
lnode *p=l->next;
while(p)
{
llength++;
p=p->next;
}
cout<<"长度为:"<<llength<<endl;
}
int main()
{
char a;
link l;
cout<<"r(创建)、t(遍历)、g(读取第i个元素)、i(插入)"<<endl;
cout<<"d(删除)、l(求长度)、c(清空)、 x(退出程序)"<<endl;
while(cin>>a&&a!='x')
{
if(check(a))
{
switch(a)
{
case 'r':creat(l); print();break;
case 't':trace(l); print();break;
case 'g':getdata(l); print();break;
case 'i':insert(l); print();break;
case 'd':del(l); print();break;
case 'l':getlength(l);print();break;
case 'c':
{
init(l);
cout<<"清空成功!"<<endl;
print();break;
}
}
}
else
cout<<"请输入正确选项!"<<endl;
}
}
运行结果:
创建单链表并遍历:
读取元素:
插入并遍历:
删除并遍历:
求表长+清空+遍历:
第二题代码:
#include<bits/stdc++.h>
#define size 100
using namespace std;
typedef struct lnode
{
int data;
struct lnode *next;
}*link,lnode;
void init(lnode *&l) //初始化
{
l=(lnode *)malloc(sizeof(lnode));
l->next=NULL; //链表带头结点; 不带头节点:l=NULL
}
void creat(lnode *&l,int n) //创建链表
{
int i,t;
init(l);
lnode *p=l,*q;
cout<<"请输入密码:";
for(i=0;i<n;i++)
{
q=(lnode *)malloc(sizeof(lnode));
cin>>t;
q->data=t;
q->next=NULL;
p->next=q;
p=q;
}
p->next=NULL;
}
void trace(lnode *l) //遍历链表
{
link p=l->next;
if(p)
{
cout<<"元素为:";
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
else
cout<<"链表为空"<<endl;
}
int main()
{
char a;
link l;
int n,m,i;
cout<<"请输入n和m:";
while(cin>>n>>m&&m>=1)
{
init(l);
creat(l,n);
trace(l);
lnode *p=l->next,*q=l,*r;
while(n&&n!=1)
{
i=1;
while(i!=m)
{
if(p&&p->next)
{
p=p->next;
q=q->next;
}
else
{
p=l->next;
q=l;
}
i++;
}
cout<<p->data<<" ";
if(p->next)
{
q->next=p->next;
r=p;
p=p->next;
free(r);
}
else
{
q->next=NULL;
r=p;
free(r);
p=l->next;
q=l;
}
n--;
}
cout<<p->data<<endl;
cout<<endl<<"请输入n和m:";
}
return 0;
}
运行结果: