实验目的
通过该实验,深入理解链表的逻辑结构、物理结构等概念,掌握链表基本操作的编程实现,熟练掌握C语言中指针的操作。
实验内容
编程实现链表下教材第二章定义的线性表的基本操作,最好用菜单形式对应各个操作,使其编程一个完整的小软件。
参考界面:
源代码
#include <iostream>
using namespace std;
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
//链表初始化
int InitList(LinkList &L)
{
L=new LNode;
if(!L) return 0;
L->next=NULL;
return 1;
}
//销毁链表
int DestoryList(LinkList &L)
{
LinkList p;
while(L)
{
p=L;
L=L->next;
delete p;
}
return 1;
}
//清空单链表
int ClearList(LinkList L)
{
LinkList p,q;
p=L->next;
while(p){q=p;delete q;p=p->next;}
L->next=NULL;
return 1;
}
//求单链表长度
int Listlength(LinkList L)
{
int sum=0;
LinkList p=L->next;
while(p)
{
p=p->next;
sum++;
}
return sum;
}
//判断单链表是否为空
bool ListEmpty(LinkList L)
{
if(L->next)
return 1;
else
return 0;
}
//获取单链表中某个数据元素的内容
int GetElem(LinkList L,int i,ElemType &e)
{
LinkList p=L->next;
int j=1;
while(p&&j<i)
{
p=p->next;
++j;
}
if(!p||j>i)return 0;
e=p->data;
return 1;
}
//查找值为e的数据元素的位置
int LocateElem(LinkList L,ElemType e)
{
LinkList p=L->next;
int i=0;
while(p&&p->data!=e)
{
p=p->next;
i++;
}
if(i>=Listlength(L))
return 0;
return i+1;
}
//求直接前驱
int PriorElem(LinkList L,ElemType e,ElemType&pre_e)
{
LNode*p=L->next;
if(e==p->data)
return 0;
while(p->next)
{
if(p->next->data==e)
{
pre_e=p->data;
return 1;
}
p=p->next;
}
return 0;
}
//求直接后继
int NextElem(LinkList L,ElemType e,ElemType&next_e)
{
LNode*p=L->next;
while(p)
{
if(p->data==e&&p->next)
{
next_e=p->next->data;
return 1;
}
p=p->next;
}
return 0;
}
//在单链表中插入数据元素
int ListInsert(LinkList&L,int i,ElemType e)
{
LinkList p=L;
int j=0;
while(p&&(j<i-1))
{
p=p->next;
++j;
}
if(!p||j>i-1)return 0;
LinkList s=new LNode;
s->data=e;
s->next=p->next;
p->next=s;
return 1;
}
//删除单链表中第i个元素,返回第i个元素的值
int ListDelete(LinkList &L,int i,ElemType&e)
{
LinkList p=L;
int j=0;
while((p->next)&&(j<i-1))
{
p=p->next;
++j;
}
if(!(p->next)||(j>i-1)) return 0;
LinkList q=p->next;
e=q->data;
p->next=q->next;
delete q;
return 1;
}
//输出链表元素
void LinkPrint(LinkList &L)
{
LinkList p=L->next;
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
}
//前插法创建单链表
void CreateList_H(LinkList &L,int n)
{
L=new LNode;
L->next=NULL;
cout<<"请输入要插入的元素:"<<endl;
for(int i=0;i<n;i++)
{
LNode*p=new LNode;
cin>>p->data;
p->next=L->next;
L->next=p;
}
}
//后插法创建单链表
void CreateList_R(LinkList&L,int n)
{
L=new LNode;
L->next=NULL;
LNode*r=L;
for(int i=0;i<n;++i)
{
LinkList p=new LNode;
cin>>p->data;
p->next=NULL;
r->next=p;
r=p;
}
}
//判断链表是否为空
bool IsEmpty(LinkList L)
{
if(L->next)
return false;
else
return true;
}
//链表逆转
int ReverseList(LinkList&L)
{
if(L==NULL||L->next==NULL)
return 0;
LinkList pRev=NULL;
LinkList pCur=L->next;
while(pCur!=NULL)
{
LinkList temp=pCur;
pCur=pCur->next;
temp->next=pRev;
pRev=temp;
}
L->next=pRev;
return 1;
}
void PrintTips()
{
cout<<"可执行的操作有:"<<endl;
cout<<"********************"<<endl;
cout<<"1.初始化或重置列表"<<endl;
cout<<"2.销毁链表"<<endl;
cout<<"3.链表中数据元素的个数"<<endl;
cout<<"4.所指位序的元素值"<<endl;
cout<<"5.链表已存在元素的位序"<<endl;
cout<<"6.请输入元素,求直接前驱"<<endl;
cout<<"7.请输入元素,求直接后继"<<endl;
cout<<"8.在第i个位置插入元素"<<endl;
cout<<"9.删除第i个元素"<<endl;
cout<<"10.输出所输入的链表元素"<<endl;
cout<<"11.初始化并输入链表元素"<<endl;
cout<<"12.退出"<<endl;
cout<<"13.判断单链表是否为空"<<endl;
cout<<"14.链表逆转"<<endl;
cout<<"********************"<<endl;
cout<<"请输入你的选择:";
}
//判断输入是否合法
bool IsInvalid(LinkList L)
{
if(L==NULL)
{
cout<<"链表未初始化!"<<endl;
return true;
}
else
return false;
}
int main()
{
int k,s,i;
ElemType e,res_e;
LNode *p;
LinkList L;
PrintTips();
while(cin>>k)
{
switch(k)
{
case 1:
s=InitList(L);
if(s==1)
cout<<"初始化成功或重置成功!"<<endl;
break;
case 2:
s=DestoryList(L);
if(s==1)
cout<<"销毁成功!"<<endl;
break;
case 3:
if(IsInvalid(L)) break;
s=Listlength(L);
cout<<"链表中数据元素个数为:"<<s<<endl;
break;
case 4:
if(IsInvalid(L)) break;
if(!L->next)
{
cout<<"链表为空!"<<endl;
break;
}
cout<<"请输入序号:";
cin>>i;
if(!GetElem(L,i,e))
{
cout<<"该位置超出链表范围!"<<endl;
break;
}
cout<<"下标"<<i<<"处元素值为:"<<e<<endl;
break;
case 5:
if(IsInvalid(L)) break;
cout<<"请输入要查找的元素:";
cin>>e;
s=LocateElem(L,e);
if(!s)
{
cout<<"不存在"<<endl;
break;
}
cout<<"值为"<<e<<"的元素下标为:"<<s<<endl;
break;
case 6:
if(IsInvalid(L)) break;
if(!L->next)
{
cout<<"链表为空!"<<endl;
break;
}
cout<<"请输入一个元素:";
cin>>e;
if(!PriorElem(L,e,res_e))
{
cout<<"查找失败!"<<endl;
break;
}
cout<<"该元素的前驱为:"<<res_e<<endl;
break;
case 7:
if(IsInvalid(L)) break;
if(!L->next)
{
cout<<"链表为空!"<<endl;
break;
}
cout<<"请输入一个元素:";
cin>>e;
if(!NextElem(L,e,res_e))
{
cout<<"查找失败!"<<endl;
break;
}
cout<<"该元素的后继为:"<<res_e<<endl;
break;
case 8:
if(IsInvalid(L)) break;
cout<<"请输入要插入的位置和元素:";
cin>>i>>e;
s=ListInsert(L,i,e);
if(s)
cout<<"插入成功!"<<endl;
else
cout<<"插入失败!"<<endl;
break;
case 9:
if(IsInvalid(L)) break;
cout<<"请输入要删除的位置:";
cin>>i;
s=ListDelete(L,i,e);
if(s)
cout<<"删除成功!,该位置值为:"<<e<<endl;
else
cout<<"删除失败!"<<endl;
break;
case 10:
if(IsInvalid(L)) break;
LinkPrint(L);
cout<<endl;
break;
case 11:
cout<<"请输入要插入链表的元素个数:";
cin>>s;
CreateList_R(L,s);
break;
case 12:
return 0;
break;
case 13:
if(IsInvalid(L)) break;
if(IsEmpty(L))
cout<<"链表为空!"<<endl;
else
cout<<"非空!"<<endl;
break;
case 14:
if(IsInvalid(L)) break;
if(ReverseList(L))
cout<<"链表逆转成功!"<<endl;
else
cout<<"操作失败!"<<endl;
break;
default:
cout<<"操作有误!"<<endl;
}
cout<<"请输入你的选择:";
}
return 0;
}