题目一:线性表的顺序表示
[问题描述]
实现带头结点的单链表的建立、求长度,取元素、修改元素、插入、删除等单链表的基本操作。
[基本要求]
(1)依次从键盘读入数据,建立带头结点的单链表;
(2)输出单链表中的数据元素;
(3)求单链表的长度;
(4)根据指定条件能够取元素和修改元素;
(5)实现在指定位置插入和删除元素的功能。
[源代码](加注释)
#include<stdio.h>
#include<iostream>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int Boolean;
typedef int ElemType;
typedef struct LNode{
int data; //结点的数据域
LNode *next; //结点的指针域
}*LinkList,LNode; //LinkList为指向结构体LNode的指针类型
void CreatList_R(LinkList &L,int n)//尾插法建立空链表
{//正位序输入n个元素的值,建立带头结点的单链表L
LinkList p,r;
L=new LNode;
L->next=NULL; //先建立一个带头结点的空链表
r=L; //尾指针r指向头结点
for(int i=0;i<n;i++)
{
p=new LNode; //生成新结点
cin>>p->data; //输入元素值赋给新结点*p的数值域
p->next=NULL;r->next=p; //将新结点*p插入尾结点*r之后
r=p; //r指向新的尾结点*p
}
}
Status getLength(LinkList L,int i)//求链表长度
{
i=0;
LinkList p;
p=L->next; //初始化,p指向首元结点
while(p) //当p不为空时
{
i++; //i+1,计数
p=p->next; //p指向下一个结点
}
return i; //返回的i即为链表长度
}
Status GetElem(LinkList L,int i,ElemType &e)//取值
{
LinkList p;
p=L->next; //初始化,p指向首元结点
int j=1; //计数器j初值附为1
while(p&&j<i) //顺链域向后扫描,直到p为空或p指向第i个元素
{
p=p->next; //p指向下一个结点
++j; //计数器j相应+1
}
if(!p||j>i) return ERROR; //i值不合法i>n或i<=0
e=p->data; //取第i个结点的数据域
return OK;
}
Status ListInsert(LinkList &L,int i,ElemType e)//插入
{//在带头结点的单链表L中第i个 位置插入值为e的新结点
LinkList p,s;
p=L;int j=0;
while(p&&(j<i-1))
{p=p->next;j++; } //查找第i-1个结点,p指向该结点
if(!p||j>i-1) return ERROR; //i>n+1或者i<1
s=new LNode; //生成新结点*s
s->data=e; //将结点*s的数据域置为e
s->next=p->next; //将结点*s的指针域指向结点ai
p->next=s; //将结点*p的指针域指向结点*s
return OK;
}
Status ListDelete(LinkList &L,int i)//删除
{//在带头结点的单链表L中,删除第i个元素
LinkList p,q;
p=L;int j=0;
while((p->next)&&(j<i-1))
{p=p->next;j++;} //查找第i-1个结点,p指向该结点
if(!(p->next)||j>i-1) return ERROR; //当i>n或i<1时,删除位置不合理
q=p->next; //临时保存被删结点的地址以备释放
p->next=q->next; //改变删除结点前驱结点的指针域
delete(q); //释放删除结点的空间
return OK;
}
void show(LinkList L)//显示链表所有元素
{
LinkList p;
p=L->next ; //初始化,p指向首元结点
while(p)
{
cout<<p->data<<"->"; //输出p的数据域
p=p->next; //p指向下一个结点
}
cout<<endl;
}
void xiugai(LinkList L)//对链表中的数据进行修改
{
int i,j=1;
int k,e,m;
LinkList p=L->next; //初始化,p指向首元结点
cout<<"请输入要修改的元素位置i(0<i<length):";
cin>>i;
GetElem(L,i,e); //获取该位置的元素
cout<<"该位置的元素:"<<e<<endl;
cout<<"请输入修改后的元素值:";
cin>>k; //输入被修改的值
while(p&&j<i)
{p=p->next;j++;} //查找第i-1个结点,p指向该结点
m=p->data; //另设m表示p的数据域
p->data=k; //用k附到p的数据域
cout<<"修改后的单链表显示如下:"<<endl;
show(L); //显示打印修改后的单链表
}
int main()
{
int x,y,n,i,e;
LinkList L;
for(;;)
{
printf("1.建立一个空链表,长度为x\n");
printf("2.获取该链表的长度\n");
printf("3.获取第i位的数值\n");
printf("4.在第i位置插入e值\n");
printf("5.删除元素的值\n");
printf("6.修改第i位置的值\n");
printf("7.单链表的显示\n");
printf("请输入选项:");
cin>>n;
switch(n){
case 1:{
cout<<"请输入单链表长度:";
cin>>x;
cout<<"请输入x个元素:";
CreatList_R(L,x);
break;
}
case 2:{
int s;
cout<<"单链表长度为:"<<getLength(L,s)<<endl;;
break;
}
case 3:{
printf("输入位置i:");
cin>>i;
GetElem(L,i,e);
printf("该地址元素为:%d\n",e);
break;
}
case 4:{
cout<<"输入第i位置:";
cin>>i;
cout<<"输入插入元素e:";
cin>>e;
ListInsert(L,i,e);
cout<<"插入后的单链表显示如下:"<<endl;
show(L);
break;
}
case 5:{
int s;
printf("输入要删除的位置i:");
cin>>i;
ListDelete(L,i);
cout<<"删除后的单链表显示如下:"<<endl;
show(L);
break;
}
case 6:{
xiugai(L);
break;
}
case 7:{
show(L);
break;
}
}
cout<<endl;
}
return 0;
}
[测试数据]
1)2)3)实现建立空链表、取元素、删除功能
4)5)6)实现修改、插入、求长度功能
7)实现单链表显示功能