实验题目;单链表基本操作
实验目的;1.掌握用 C/C++语言调试程序的基本方法。
2.掌握线性表的基本运算,如插入、删除等
• 实验内容;编写程序实现单链表的各种基本运算,并在此基础上设计一个主程序完成如下功能:
• (1)初始化单链表h;
• (2)依次采用头插法插入元素-1,21,13,24,8;
• (3)输出单链表h;
• (4)输出单链表h长度;
• (5)判断单链表h是否为空;
• (6)输出单链表h的第3个元素;
• (7)输出元素24的位置;
• (8)在h的第4个元素前插入元素0;
• (9)输出单链表h;
• (10)删除h的第5个元素;
• (11)输出单链表h。
PS:Linklist &L是引用传递,可以起到修改链表的作用,而Linklist L是值传递,只是拷贝一份副本,对副本的任何操作都无法起到修改链表的作用。
Elemtype e和Elemtype &e也是同理
#include <bits/stdc++.h>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status;
typedef int Boolean;
typedef int ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
int InitList(LinkList &L)
{ // 操作结果:构造一个空的线性表L
L = (LinkList)malloc(sizeof(LNode)); // 产生头结点,并使L指向此头结点
if(!L) // 存储分配失败
exit(OVERFLOW);
L -> next = NULL; // 指针域为空
}
int DestroyList(LinkList &L)
{ // 初始条件:线性表L已存在。操作结果:销毁线性表L
LinkList q;
while(L)
{
q = L -> next;
free(L);
L = q;
}
}
int ClearList(LinkList L) // 不改变L
{ // 初始条件:线性表L已存在。操作结果:将L重置为空表
LinkList p,q;
p = L -> next; // p指向第一个结点
while(p) // 没到表尾
{
q = p -> next;
free(p);
p = q;
}
L -> next = NULL; // 头结点指针域为空
}
Status ListEmpty(LinkList L)
{ // 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE
if(L -> next) // 非空
return FALSE;
else
return TRUE;
}
int ListLength(LinkList L)
{ // 初始条件:线性表L已存在。操作结果:返回L中数据元素个数
int i = 0;
LinkList p = L -> next; // p指向第一个结点
while(p) // 没到表尾
{
i++;
p = p -> next;
}
return i;
}
Status GetElem(LinkList L,int i,ElemType &e) // 算法2.8
{ // L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
int j = 1; // j为计数器
LinkList p = L -> next; // p指向第一个结点
while(p && j < i) // 顺指针向后查找,直到p指向第i个元素或p为空
{
p = p -> next;
j++;
}
if(!p || j > i) // 第i个元素不存在
return ERROR;
e = p -> data; // 取第i个元素
return OK;
}
int LocateElem(LinkList L,ElemType e)
{ // 初始条件: 线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)
// 操作结果: 返回L中第1个与e满足关系compare()的数据元素的位序。
// 若这样的数据元素不存在,则返回值为0
int i = 0;
LinkList p = L -> next;
while(p)
{
i++;
p = p -> next;
}
return i;
}
Status PriorElem(LinkList L,ElemType cur_e,ElemType &pre_e)
{ // 初始条件: 线性表L已存在
// 操作结果: 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,
// 返回OK;否则操作失败,pre_e无定义,返回INFEASIBLE
LinkList q,p = L -> next; // p指向第一个结点
while(p -> next) // p所指结点有后继
{
q = p -> next; // q为p的后继
if(q -> data == cur_e)
{
pre_e = p -> data;
return OK;
}
p = q; // p向后移
}
return INFEASIBLE;
}
Status NextElem(LinkList L,ElemType cur_e,ElemType &next_e)
{ // 初始条件:线性表L已存在
// 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,
// 返回OK;否则操作失败,next_e无定义,返回INFEASIBLE
LinkList p = L -> next; // p指向第一个结点
while(p) // 查找结点cur_e
{
if(p -> data == cur_e)
break; //找到就跳出循环
p = p -> next;
}
if(p && p -> next)
{
next_e = p -> next -> data;
return OK;
}
return INFEASIBLE;
}
Status ListInsert(LinkList L,int i,ElemType e) // 算法2.9。不改变L
{ // 在带头结点的单链线性表L中第i个位置之前插入元素e
int j = 0;
LinkList p = L,s;
while(p && j < i - 1) // 寻找第i-1个结点
{
p = p -> next;
j++;
}
if(!p || j > i - 1) // i小于1或者大于表长
return ERROR;
s = (LinkList)malloc(sizeof(LNode)); // 生成新结点
s -> data = e; // 插入L中
s -> next = p -> next;
p -> next = s;
return OK;
}
Status ListDelete(LinkList L,int i,ElemType &e) // 算法2.10。不改变L
{ // 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
int j = 0;
LinkList p = L,q;
while(p -> next && j < i - 1) // 寻找第i个结点,并令p指向其前驱
{
p = p -> next;
j++;
}
if(!p -> next || j > i - 1) // 删除位置不合理
return ERROR;
q = p -> next; // 删除并释放结点
p -> next = q -> next;
e = q -> data;
free(q);
return OK;
}
void ListTraverse(LinkList L,void(*vi)(ElemType))
// vi的形参类型为ElemType,与bo2-1.cpp中相应函数的形参类型ElemType&不同
{ // 初始条件:线性表L已存在。操作结果:依次对L的每个数据元素调用函数vi()
LinkList p = L -> next;
while(p)
{
vi(p -> data);
p = p -> next;
}
cout << endl;
}
int main()
{
LinkList h;
ElemType e;
cout << "①初始化链表h" << endl;
InitList(h);
cout << "②插入元素-1,21,13,24,8" << endl;
ListInsert(h,1,-1);
ListInsert(h,2,21);
ListInsert(h,3,13);
ListInsert(h,4,24);
ListInsert(h,5,8);
cout << "③输出单链表h:" << endl;
for(int m = 1; m <= ListLength(h); m++)
{
GetElem(h,m,e);
cout << e << " ";
}
cout << endl;
cout << "④单链表h的长度为:" << ListLength(h) << endl;
cout << "⑤判断单链表是否为空:";
if(ListEmpty(h) == TRUE)
cout << "空" << endl;
else
cout << "不空" << endl;
GetElem(h,3,e);
cout << "⑥第三个元素:" << e << endl;
cout << "⑦元素24的位置为:" << LocateElem(h,24) << endl;
cout << "⑧第四个元素前插入0" << endl;
ListInsert(h,4,0);
cout << "⑨输出单链表h:" << endl;
for(int m = 1; m <= ListLength(h); m++)
{
GetElem(h,m,e);
cout << e << " ";
}
cout << endl;
cout << "⑩删除h的第五个元素:" << endl;
ListDelete(h,5,e);
cout << "输出单链表h:" << endl;
for(int m = 1; m < ListLength(h); m++)
{
GetElem(h,m,e);
cout << e <<" ";
}
return 0;
}