一、实验目的
1.掌握线性表的链式表示;
2.掌握链式表的建立、插入、删除、查找等相关操作;
3.会利用链式表解决相关问题。
二、实验任务
实现线性表(a,b,c,d,e,f,g,h)的链式表示及相关操作。
1.建立一个空链表;
2.空表中添加元素,并打印输出线性表元素;
3.获取线性表中第3个元素,并打印输出该元素;
4.查找线性表中第一个与f相等的元素,并返回其地址;
5.在表尾插入一个你最喜欢的元素,并打印插入后线性表中的元素;
6.删除线性表中的第2个元素,并打印删除后线性表中的元素。
三、预习环节
1.指针变量p:表示结点地址
结点变量*p:表示一个结点
2.结构体定义:
(1)struct 结构体名
{类型名 成员名1;
...
类型名 成员名n;
};
(2)struct 结构体名
{类型名 成员名1;
...
类型名 成员名n;
};
struct 结构体名 结构体变量名表;
(3)struct 结构体名
{类型名 成员名1;
...
类型名 成员名n;
};结构体变量名表
四、实验内容
1.代码
#include<iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW 2
typedef int Status;
typedef char ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
//建立一个空表
Status InitList(LinkList &L)
{
L = new LNode;
L->next = NULL;
return OK;
}
//后插法创建单链表
void CreateList_R(LinkList &L, int n)
{
LinkList p, r;
int i;
L = new LNode;
L->next = NULL;
r = L;
for(i=0;i<n;++i)
{
p=new LNode;
cin>>p->data;
p->next=NULL; r->next=p;
r=p;
}
}
//获取线性表中的元素
Status GetElem(LinkList L, int i, ElemType &e)
{
int j;
LinkList p;
p = L->next; j = 1;
while (p && j<i )
{
p = p->next;
++j;
}
if (!p || j > i)return ERROR;
e = p->data;
return OK;
}
//查找元素并返回地址
LNode *LocateElem(LinkList L, ElemType e)
{
LinkList p;
p = L->next;
while (p && p->data!= e)
p = p->next;
return p;
}
//查找元素并返回位置
int weizhi(LinkList L, ElemType e)
{
LinkList p;
p = L->next;
int j=1;
while (p && p->data!= e)
{p = p->next;
j++;}
return j;
}
//在第i个位置插入元素
Status ListInsert(LinkList &L, int i, ElemType e)
{
int j;
LinkList p, s;
p = L;
j = 0;
while (p && (j < i - 1))
{
p = p->next;
++j;
}
if (!p || j > i - 1) return ERROR;
s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
//删除元素
Status ListDelete(LinkList &L, int i)
{
LinkList p, q;
int j;
p = L;
j = 0;
while ((p->next) && (j < i - 1))
{
p = p->next;
++j;
}
if (!(p->next) || (j > i - 1)) return ERROR;
q = p->next;
p->next = q->next;
delete q;
return OK;
}
void main()
{
LinkList L;
InitList(L);
int n;
cout<<"输入元素个数:"<<endl;
cin>>n;
cout<<"输入线性表的元素:"<<endl;
CreateList_R(L,n);
LNode*p;
int i;
p=L->next;//把p从首元节点开始
//打印链表
cout<<"打印单链表"<<endl;
for(i=0;i<n;++i)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
int w;
cout<<"获取线性表中第w个元素 w为:"<<endl;
cin>>w;
char e;//元素是字符串类型
GetElem(L,w,e);
cout<<"获取线性表中第w个元素的值为:"<<endl;
cout<<e<<endl;
char x={'f'};
LNode*m;
m=LocateElem(L,x);
cout<<"查找链表中第一个值与f相等的元素的地址:"<<endl;
cout<<m<<endl;
cout<<"查找链表中第一个值与f相等的元素的位置:"<<endl;
int j;
j=weizhi(L,x);
cout<<j<<endl;
char k={'a'};
ListInsert(L,9,k);
//打印链表
cout<<"打印插入后单链表的元素"<<endl;
p=L->next;//把p从首元节点开始
//打印链表
for(i=0;i<n+1;++i)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
int a;
cout<<"删除第a个元素 a为:";
cin>>a;
ListDelete(L,a);
cout<<"打印删除后单链表的元素"<<endl;
p=L->next;
for(i=0;i<n;++i)
{
cout<<p->data<<" ";
p=p->next;
}
}
2.程序调试过程
(1)线性表中的元素为字母为字符串类型 char
(2)打印单链表的时候用的for循环 结束条件i<n 注意结束条件n为表长 前面操作有时候删除元素 有时候插入
(3)把p从首元节点开始 p=L->next;
(4)忘记定义指针
(5)实现创新查找元素并返回位置时while 后语句忘加{}导致j++没放进循环 返回位置一直为2
3、运行结果
五、能力提升
在查找与f相等的元素返回位置
//查找元素并返回位置
int weizhi(LinkList L, ElemType e)
{
LinkList p;
p = L->next;
int j=1;
while (p && p->data!= e)
{p = p->next;
j++;}
return j;
}
六、总结与讨论
1.遇到问题:
(1)有时候不确定i范围 例如插入操作中:合法插入位置有n+1个,即1<=i<=n+1
(2)线性表中的元素为字母为字符串类型 char
(3)打印单链表的时候用的for循环 结束条件i<n 注意结束条件n为表长 前面操作有时候删除元素 有时候插入
2.总结体会:
(1)定义函数时注意返回值
(2)掌握了线性表的链式表示和单链表的操作
(3)学会利用链式表解决相关问题