1.实验目的
(1)掌握线性表的链式存储结构;
(2)掌握单链表及其基本操作的实现。
2.实验内容
(1)编程实现单链表的以下基本操作:建立单链表,查找单链表,插入单链表,删除单链表。
(2)采用单链表结构编程实现:两个有序单链表的归并运算。
3.实验步骤
- 编写程序框架,利用while循环输入操作代码,利用switch选择语句对输入的代码进行判断,并进行相应操作。
- 编写各个操作的具体函数:
1>建立单链表:初始化单链表并输入元素;
2>查找元素:顺链域向后扫描,直到p为空或p指向第i个元素;
3>定位元素:顺链域向后扫描,直到p为空或p所指结点数据域等于e;
4>插入单链表:新结点的指针域指向插入位置,将插入位置前驱的指针域指向新结点;
5>删除单链表:改变删除结点前驱的指针域,释放被删除结点;
6>显示单链表:while循环输出元素,直到p为空;
7>两个有序单链表归并:创建两个有序单链表LA,LB,一次比较两个表中的元素,将较小的值插入到LC中。 - 执行代码,测试数据。
4.实验代码
#include <iostream>
using namespace std;
typedef int ElemType;
typedef struct LNode
{
ElemType data; //结点的数据域
struct LNode *next; //结点的指针域
}LNode,*LinkList;
//创建单链表(尾插法)
void CreateList(LinkList &L);
//显示单链表
void ListDisplay(LinkList &L);
//查找元素
void GetElem(LinkList &L,int i,ElemType e);
//定位元素
LNode *LocateElem(LinkList &L,ElemType e);
//插入单链表
void ListInsert(LinkList &L,int i,ElemType e);
//删除单链表
void ListDelete(LinkList &L,int i);
//两个有序单链表归并
void MergeList(LinkList &LA,LinkList &LB,LinkList &LC);
int main()
{
LinkList L,LA,LB,LC;
ElemType e;
int n;
int index = 1;
while(index > 0)
{
cout << "###### 1812050030-戴琦 ######" << endl;
cout << "1-------创建单链表" << endl;
cout << "2-------查找元素" << endl;
cout << "3-------定位元素" << endl;
cout << "4-------插入单链表" << endl;
cout << "5-------删除单链表" << endl;
cout << "6-------显示单链表" << endl;
cout << "7-------两个有序单链表归并" << endl;
cout << "请输入操作序号:";
cin >> index;
switch(index)
{
case 1:
CreateList(L);
break;
case 2:
cout << "请输入要查找的位置:";
cin >> n;
GetElem(L,n,e);
break;
case 3:
cout << "请输入要定位的元素:";
cin >> e;
LocateElem(L,e);
break;
case 4:
cout << "请输入要插入的位置:";
cin >> n;
cout << "请输入要插入的元素:";
cin >> e;
ListInsert(L,n,e);
break;
case 5:
cout << "请输入要删除结点的位置:";
cin >> n;
ListDelete(L,n);
break;
case 6:
ListDisplay(L);
break;
case 7:
cout << "请创建两个有序单链表:" << endl;
cout << "LA:";
CreateList(LA);
cout << "LB:";
CreateList(LB);
MergeList(LA,LB,LC);
break;
default:
cout << "输入数据不合法!" << endl;
}
}
return 0;
}
void CreateList(LinkList &L)
{
int n;
cout << "请输入链表长度:";
cin >> n;
L = new LNode;
L->next = NULL;
LinkList r = L;
for(int i=0;i<n;i++)
{
LinkList p = new LNode;
cin >> p->data;
p->next = NULL;
r->next = p;
r = p;
}
}
void ListDisplay(LinkList &L)
{
LinkList p = L->next;
while(p)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
void 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)
{
cout << "输入位置不合法!" << endl;
return;
}
e = p->data;
cout << "该位置的元素为:" << e << endl;
}
LNode *LocateElem(LinkList &L,ElemType e)
{
LinkList p = new LNode;
p = L->next;
while(p && p->data != e)
p = p->next;
if(p)
cout << "此元素的存储地址为:" << p << endl;
else
cout << "单链表中无此元素!" << endl;
return p;
}
void 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)
{
cout << "插入失败!" << endl;
return;
}
LinkList s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
cout << "插入成功!" << endl;
}
void ListDelete(LinkList &L,int i)
{
LinkList p = L;
int j = 0;
while(p->next && j<i-1)
{
p = p->next;
++j;
}
if(!p->next || j>i-1)
{
cout << "删除失败!" << endl;
return;
}
LinkList q = p->next;
p->next = q->next;
delete q;
cout << "删除成功!" << endl;
}
void MergeList(LinkList &LA,LinkList &LB,LinkList &LC)
{
LinkList pa,pb,pc;
pa = LA->next;
pb = LB->next;
LC = LA;
pc = LC;
while(pa&&pb)
{
if(pa->data <= pb->data)
{
pc->next = pa;
pc = pa;
pa = pa->next;
}
else
{
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
pc->next = pa?pa:pb;
delete LB;
cout << "归并后的单链表LC为:" << endl;
ListDisplay(LC);
}
5.实验总结
(1) 创建单链表时,插入元素的顺序与插入方法有关。
(2) 如果有n个结点,插入操作中合法插入位置有n+1个,删除操作合法位置有n个。
(3) 因为链表结点之间的关系是通过指针指向建立起来的,所以用链表进行合并不需要另外开辟存储空间,可以直接利用原来两个表的存储空间,合并过程中只需把两个表的结点重新进行链接即可。