实验3、单链表的基本操作实现
(1)实验目的
通过该实验,深入理解链表的逻辑结构、物理结构等概念,掌握链表基本操作的编程实现,熟练掌握C语言中指针的操作。和实验3对比,掌握线性结构两种不同存储方式的区别。
(2)实验内容
编程实现链表下教材第二章定义的线性表的基本操作,最好用菜单形式对应各个操作,使其编程一个完整的小软件。注意,每个功能模块一定要考虑非法的情况,并作出相应的提示,例如:求前驱,要分别能够测试第一个元素的前驱、其他正常的元素的前驱、输入一个在表中不存在的元素求其前驱,这三种情况应给出相应的提示语和结果值;插入和删除时要考虑插入或删除的位置是否合法等。
(3)实验要求:
菜单项包括:
1.初始化或重置链表
2.销毁链表
3.清空链表
4.链表长度
5.指定位置的元素值
6.链表已存在元素的位序
7.求输入元素的直接前驱
8.求输入元素的直接后继
9.在第i个位置插入一个元素
10.删除第i个元素
11.输出有的链表元素
12.初始化并用头插法(或尾插法)输入元素
13.实现单链表的逆序存放
要求:所有的提示语不允许出现在自定义的函数中,只能在main函数中出现提示语。
#include<iostream>
#include<stdlib.h>
#include<conio.h>
using namespace std;
#define ok 1
#define error 0
#define question -1
#define shortcoming 2
typedef int Status;
typedef int ElemType;
typedef struct LNode{
struct LNode *next;
ElemType data;
}LNode , *linklist;
Status init(linklist &L); //初始化或重置链表
Status Destroy(linklist &L); //销毁链表
Status Empty(linklist &L); //清空链表
Status GetLength(linklist L); //获取链表长度
Status GetElem(linklist L, ElemType &e,int j); //获取指定位置元素
Status GetLoc(linklist L, int &e,int &j); //获取指定元素位置
Status GetPrior(linklist L ,int &e,int j); //获取指定元素前驱
Status GetNext(linklist L ,int &e,int j); //获取指定元素后继
Status Insert(linklist &L,int &e,int &j); //在指定位置插入元素
Status Delete(linklist &L,int &j); //删除指定位置元素
Status shuchu(linklist L); //显示链表中全部元素
Status shuru(linklist &L); //初始化并用头插法插入数据
Status nixu(linklist &L); //链表元素的逆序存放
int menu() {
cout<<"1----初始化或重置链表"<<endl;
cout<<"2----销毁链表"<<endl;
cout<<"3----清空链表"<<endl;
cout<<"4----求链表长度"<<endl;
cout<<"5----获取链表中指定位置的元素"<<endl;
cout<<"6----获取线性表元素的位置"<<endl;
cout<<"7----求前驱"<<endl;
cout<<"8----求后继"<<endl;
cout<<"9----在链表指定位置插入元素"<<endl;
cout<<"10---删除链表指定位置的元素"<<endl;
cout<<"11---显示链表"<<endl;
cout<<"12---初始化并用头插法(尾插法)输入元素"<<endl;
cout<<"13---实现链表的逆序存放"<<endl;
cout<<" 退出,输出一个负数!"<<endl;
}
int main() {
int a;
linklist L = NULL;
menu();
while(true) {
cout<<"请选择程序:";
cin>>a;
if (a < 0) {
cout<<"程序已退出!"<<endl;
break;
}
if(a == 0 || a > 13) {
cout<<"程序选择错误!请重新选择:";
getch();
continue;
}
if (a > 0 && a < 14) {
switch(a) {
case 1:{
if(init(L) == ok) {
cout<<"链表初始化成功!"<<endl;;
} else if (init(L) == error){
cout<<"链表初始化失败!"<<endl;
} else {
cout<<"链表重置成功!"<<endl;
}
break;
}
case 2:{
if(Destroy(L) == ok) {
cout<<"链表已销毁!"<<endl;
} else if (Destroy(L) == question) {
cout<<"链表不存在"<<endl;
} else {
cout<<"链表销毁失败,请重试!"<<endl;
}
break;
}
case 3:{
if (Empty(L) == ok) {
cout<<"链表已清空!"<<endl;
} else if (Empty(L) == question) {
cout<<"链表为空,无需此操作!"<<endl;
} else {
cout<<"链表不存在!"<<endl;
}
break;
}
case 4:{
if (GetLength(L) == error) {
cout<<"链表不存在或链表为空!"<<endl;
} else {
cout<<"链表长度为"<<GetLength(L)<<endl;
}
break;
}
case 5:{
int e,j;
if (GetElem(L,e,j) == error) {
cout<<"链表不存在!"<<endl;
} else {
if (GetElem(L,e,j) == shortcoming) {
cout<<"链表为空!"<<endl;
} else {
cout<<"请输入想要查询的位置:";
cin>>j;
if (GetElem(L,e,j) == ok) {
cout<<"该位置的元素为:";
cout<<e<<endl;
} else {
cout<<"链表中没有该位置!"<<endl;
}
}
}
break;
}
case 6:{
int e,j;
if (L) {
if (GetLength(L) == 0) {
cout<<"链表为空!"<<endl;
} else {
cout<<"请输入要查询的元素:";
cin>>e;
if (GetLoc(L,e,j) == ok) {
cout<<"该元素的位置是:"<<j<<endl;
} else{
cout<<"表中没有该元素!"<<endl;
}
}
} else {
cout<<"链表不存在!"<<endl;
}
break;
}
case 7:{
int e,j;
if (GetPrior(L,e,j) == error) {
cout<<"链表不存在或者链表为空,请程序3进行验证!"<<endl;
} else {
cout<<"请输入想要查询前驱的元素(第一次出现):";
cin>>j;
if (GetPrior(L,e,j) == question) {
cout<<"链表中没有该元素!"<<endl;
} else if (GetPrior(L,e,j) == shortcoming) {
cout<<"该元素在链表中的第一个位置,没有前驱元素!"<<endl;
} else {
cout<<"该元素的前驱元素为:";
cout<<e<<endl;
}
}
break;
}
case 8:{
int e,j;
if (GetNext(L,e,j) == error) {
cout<<"链表不存在或者链表为空,请程序3进行验证!"<<endl;
} else {
cout<<"请输入想要查询后继的元素(第一次出现):";
cin>>j;
if (GetNext(L,e,j) == question) {
cout<<"链表中没有该元素!"<<endl;
} else if (GetNext(L,e,j) == shortcoming) {
cout<<"该元素在链表中的最后一个位置,没有后继元素!"<<endl;
} else {
cout<<"该元素的后继元素为:";
cout<<e<<endl;
}
}
break;
}
case 9:{
if (L) {
int e,j;
cout<<"请输入想要插入元素的位置:";
cin>>j;
if (j > 0 && j <= GetLength(L) + 1) {
cout<<"请输入想要插入的元素:";
cin>>e;
if (Insert(L,e,j)) {
cout<<"插入成功!"<<endl;
} else {
cout<<"插入失败!"<<endl;
}
} else {
cout<<"该位置不存在!"<<endl;
}
} else {
cout<<"线性表不存在!"<<endl;
}
break;
}
case 10:{
if (L) {
int j;
cout<<"请输入想要删除元素的位置:";
cin>>j;
if (j > 0 && j <= GetLength(L)) {
if (Delete(L,j)) {
cout<<"删除成功!"<<endl;
} else {
cout<<"删除失败!"<<endl;
}
} else {
cout<<"该位置不存在!"<<endl;
}
} else {
cout<<"线性表不存在!"<<endl;
}
break;
}
case 11:{
if (shuchu(L)) {
cout<<"数据已全部输出!"<<endl;
} else {
cout<<"链表不存在!"<<endl;
}
break;
}
case 12:{
cout<<"请开始输入元素,(以'-99'结束)"<<endl;
if (shuru(L) == error) {
cout<<"链表初始化失败!"<<endl;
} else {
cout<<"链表元素输入完成!"<<endl;
}
break;
}
case 13:{
if (L) {
if (L->next == NULL) {
cout<<"链表为空!"<<endl;
} else {
if (nixu(L) == ok) {
cout<<"程序执行成功!"<<endl;
} else {
cout<<"程序出现错误,请联系技术人员"<<endl;
}
}
} else {
cout<<"链表不存在"<<endl;
}
break;
}
}
}
}
}
Status init(linklist &L) { //1初始化或重置链表
if (L) {
Empty(L);
// L->next == NULL;
return question;
} else {
L = (linklist)malloc(sizeof(LNode));
if (L) {
L->next = NULL;
// L->data = 0;
return ok;
} else {
return error;
}
}
}
Status Destroy(linklist &L) { //2销毁链表
if(L) {
Empty(L);
L = NULL;
return ok;
} else {
return question;
}
}
Status Empty(linklist &L) { //3清空链表
if (L) {
if (L->next != NULL) {
LNode *p,*q;
p = L;
while(p->next != NULL) {
q = p->next;
p->next = q->next;
free(q);
}
return ok;
} else {
return question;
}
} else {
return error;
}
}
Status GetLength(linklist L) { //4获取链表长度
if (L) {
int i = 0;
LNode *p,*q;
p = L;
while(p->next != NULL) {
q = p->next;
p=q;
i++;
}
return i;
} else {
return error;
}
}
Status GetElem(linklist L, ElemType &e,int j) { //5获取指定位置元素
if (L) {
if (GetLength(L) == 0) {
return shortcoming;
} else {
int i = 0;
LNode *p,*q;
p = L;
if (j <= 0 || j > GetLength(L)) {
return question;
}
while(p->next != NULL) {
q = p->next;
p=q;
i++;
if (i == j) {
e = p->data;
}
}
return ok;
}
} else {
return error;
}
}
Status GetLoc(linklist L, int &e,int &j) { //6获取指定元素位置
int i = 0,flag = 0;
LNode *p,*q;
p = L;
while(p->next != NULL) {
q = p->next;
p=q;
i++;
if (p->data == e) {
j = i;
flag++;
return ok;
}
}
if (flag == 0) {
return question;
}
}
Status GetPrior(linklist L,int &e,int j) { //7获取指定元素前驱
if (L && GetLength(L) != 0) {
int i = 0,flag = 0,k = 0;
LNode *p,*q;
p = L;
while(p->next != NULL) {
q = p->next;
p=q;
i++;
if (p->data == j) {
flag = 1;
break;
}
}
if (flag == 0) {
return question;
} else {
if (i == 1) {
return shortcoming;
} else {
p = L;
while(p->next != NULL) {
q = p->next;
p=q;
k++;
if (k == i - 1) {
e = p->data;
break;
}
}
return ok;
}
}
} else {
return error;
}
}
Status GetNext(linklist L ,int &e,int j) { //8获取指定元素前驱
if (L && GetLength(L) != 0) {
int i = 0,flag = 0,k = 0;
LNode *p,*q;
p = L;
while (p->next != NULL) {
q = p->next;
p = q;
i++;
if (p->data == j) {
if (i == GetLength(L)) {
return shortcoming;
} else {
q = p->next;
p = q;
e = p->data;
flag = 1;
return ok;
}
}
}
if (flag == 0) {
return question;
}
} else {
return error;
}
}
Status Insert(linklist &L,ElemType &e,int &j) { //9在指定位置插入元素
int i = 1;
LNode *p,*s;
p = L;
while (p && i < j) {
p = p->next;
++i;
}
s = (linklist)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return ok;
}
Status Delete(linklist &L,int &j) { //10删除指定位置元素
int i = 1;
LNode *p,*q,*r;
p = L;
while (p->next && i < j) { //循环遍历链表,直到找到第j个元素
p = p->next; //p指向像一个结点
++i;
}
q = p->next;
p->next = q->next;
free(q);
return ok;
}
Status shuchu(linklist L) { //11示链表中全部元素
if (L) {
LNode *p,*q;
p = L;
while (p->next != NULL) {
q = p->next;
p = q;
// cout<<1<<endl;
cout<<p->data<<" ";
}
return ok;
} else {
return error;
}
}
Status shuru(linklist &L) { //12初始化并用头插法插入数据
init(L);
if (L) {
int i;
LNode *p,*q;
p = L;
while (true) {
cin>>i;
if (i == -99) {
break;
} else {
q = (linklist)malloc(sizeof(LNode));
q->data = i;
q->next = p->next;
p->next = q;
p = q;
}
}
return ok;
} else {
return error;
}
}
Status nixu(linklist &L) { //13 逆序存放链表
ElemType t;
int x = 1,y = 1,j = 0;
LNode *p,*q;
p = L;
q = p;
for (int i = 0;i < GetLength(L);i++) {
p = p->next;
t = p->data;
while (q->next != NULL) {
q = q->next;
j++;
if (i + j == GetLength(L)) {
p->data = q->data;
q->data = t;
break;
} else {
continue;
}
}
}
return ok;
}
刚开始接触CSND,没有写博客的经验,就直接上代码和要求了,