数据结构实验3---单链表的基本操作实现

(1)实验目的

通过该实验,深入理解链表的逻辑结构、物理结构等概念,掌握链表基本操作的编程实现,熟练掌握C语言中指针的操作。和实验2对比,掌握线性结构两种不同存储方式的区别。

(2)实验内容

编程实现链表下教材第二章定义的线性表的基本操作,最好用菜单形式对应各个操作,使其编程一个完整的小软件。注意,每个功能模块一定要考虑非法的情况,并作出相应的提示,例如:求前驱,要分别能够测试第一个元素的前驱、其他正常的元素的前驱、输入一个在表中不存在的元素求其前驱,这三种情况应给出相应的提示语和结果值;插入和删除时要考虑插入或删除的位置是否合法等。

(3)实验要求:

菜单项包括:

1.初始化或重置链表

2.销毁链表

3.清空链表

4.链表长度

5.指定位置的元素值

6.链表已存在元素的位序

7.求输入元素的直接前驱

8.求输入元素的直接后继

9.在第i个位置插入一个元素

10.删除第i个元素

11.输出有的链表元素

12.初始化并用头插法(或尾插法)输入元素

13.实现单链表的逆序存放

要求:所有的提示语和输出语句不允许出现在自定义的函数中(输出函数除外),只能在main函数中出现提示语。

注:销毁链表时需要循环释放每个结点所占用的空间。

注:求前驱是指,输入一个元素值(而不是位置),求该元素在顺序表中的直接前驱元素值。求后继是指:输入一个元素值(而不是位置),求该元素在顺序表中的直接后继元素值。

(4)验收/测试用例

参考实验2

#include<iostream>
using namespace std;
typedef int ElemType;
typedef int Status;
typedef struct Lnode {
	ElemType data; //数据域
	struct Lnode* next;//指针域
}Lnode, * LinkList;
#define OK 1
#define ERROR 0

//1.初始化或重置链表
Status InitList(LinkList& L) {
	L = (LinkList)malloc(sizeof(Lnode));//申请内存空间
	if (L == NULL) {
		exit(OVERFLOW);
	}//内存空间分配失败,退出程序,并返回OVERFLOW的值给主调进程
	L->next = NULL;//next节点指向空
	return OK;
}

//2.销毁链表
Status DeleteList(LinkList& L) {
	LinkList p;//定义一个指针
	while (L) {//while循环重复进行,实现释放全部节点
		p = L;//设置一个指针p与头指针相投,并依次断开头部指针
		L = L->next;
		free(p);//释放节点的内存
	}
	L = NULL;//设置头指针为空
	return OK;
}

//3.清空链表
Status ClearList(LinkList& L) {
	LinkList p, q;//定义两个指针
	p = L->next;//p为首元节点
	if (!p) {//p不存在的情况下,链表中不存在元素,返回错误
		return ERROR;
	}
	while (p) {//当p存在时进行循环
		q = p->next;//q为p的下一个节点
		free(p);//释放p的空间
		p = q;//令p与下一个节点相连
	}
	L->next = NULL;//设置头指针为空
	return OK;
}

//4.链表长度
Status ListLength(LinkList& L) {
	int i = 0;//定义一个整型变量并初始化为0,代表头节点
	LinkList p;//定义一个指针
	p = L;//p指向头节点
	while (p->next) {//当p指向的地址不为空时,进入循环
		p = p->next;//p指向下一个节点
		i++;//当节点不为空时,i加1,直到p指向的地址为空时结束
	}
	return i;//返回长度值
}

//5.指定位置的元素值
Status GetElem(LinkList L, int i, ElemType& e) {
	LinkList p;
	p = L->next;//p指向首元节点
	int j = 1;
	while (p && j < i) {//while循环寻找所求元素的位置,当p不为空并且j<输入位置时进入循环
		p = p->next;
		++j;
	}
	if (!p || j > i) {//当输入的位置过大或过小时,输出错误
		return ERROR;
	}
	e = p->data;
	return e;
}

//6.链表已存在元素的位序
Status ListLocate(LinkList& L, int&i, ElemType e) {
	LinkList p;
	i = 1;
	p = L->next;//p指向首元节点
	while (p) {//当p不为空时,进入循环
		if (p->data == e) {//当元素等于输入数字时,结束循环
			return OK;
		}
		i++;
		p = p->next;//p等于p的下一个元素
	}
	return ERROR;//当表中的所有元素都不相等时,返回错误
}

//7.求输入元素的直接前驱
Status PriorList(LinkList L, ElemType& e) {
	LinkList p, q = nullptr;
	int i = 1;
	p = L->next;
	while (p != NULL) {
		if (p->data == e && i != 1)
		{
			return q->data;

		}
		else if (p->data==e&&i==1) 
		{
			return ERROR;
		}
		q = p;
		p = p->next;
		i++;
	}
	return ERROR;
}
//8.求输入元素的直接后继
Status NextList(LinkList L, ElemType& e) {
	int i = 0;
	LinkList p;
	p = L;
	while (p != NULL)
	{
		if (p->data == e)
		{
			if (p->next != NULL)
				return p->next->data;
			else
				return ERROR;
		}
		p = p->next;
	}
	return ERROR;
}
//9.在第i个位置插入一个元素
Status ListInsert(LinkList& L, int i, ElemType& e) {
	LinkList p, s;
	p = L;
	int j = 0;
	while (p && j < i - 1) {
		p = p->next;
		++j;
	}
	if (!p || j > i - 1) {
		return ERROR;
	}
	s = (LinkList)malloc(sizeof(Lnode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}

//10.删除第i个元素
Status ListDelete(LinkList& L, int i) {
	LinkList p, s;
	int j = 0;
	p = L;
	while (p->next && j < i - 1) {
		p = p->next;
		++j;
	}
	if (!p->next || j > i - 1) {
		return ERROR;
	}
	s = p->next;
	p->next = s->next;
	free(s);
	return OK;
}

//11.输出所有的链表元素
Status OutPutList(LinkList& L) {
	LinkList p;
	p = L;
	if (p->next == NULL) {//当链表为空时,直接输出错误
		return ERROR;
	}
	while (p->next != NULL) {
		p = p->next;
		cout << p->data << "  ";
	}
	return OK;
}
//12.初始化并用头插法(或尾插法)输入元素
// 头插法
Status HeadList(LinkList& L, int n) {
	LinkList p;
	int i;
	L = (LinkList)malloc(sizeof(Lnode));
	L->next = NULL;
	for (i = n;i > 0;i--) {
		p = (LinkList)malloc(sizeof(Lnode));
		cin >> p->data;
		p->next = L->next;
		L->next = p;
		//L->next = L;
	}
	OutPutList(L);
	return OK;
}
// 尾插法
Status TailList(LinkList& L, int n, ElemType& e) {
	LinkList p, q;
	int i;
	L = (LinkList)malloc(sizeof(Lnode));
	L->next = NULL;
	p = L;
	for (i = 0;i < n;i++) {
		q = (LinkList)malloc(sizeof(Lnode));
		cin >> e;
		q->data = e;
		q->next = NULL;
		p->next = q;
		p = p->next;
	}
	OutPutList(L);
	return OK;
}
//13.实现单链表的逆序存放
Status ListInverse(LinkList& L) {
	LinkList p, q;
	p = L->next;
	L->next = NULL;
	while (p) {
		q = p;
		///
		p = p->next;
		q->next = L->next;
		L->next = q;
	}
	OutPutList(L);
	return OK;
}

int main() {
	LinkList L = 0;
	bool initlist = false;
	ElemType e = 0;
	int op = 0;
	int i;
	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.在第i个位置插入一个元素" << endl;
	cout << "10.删除第i个元素" << endl;
	cout << "11.输出所有的链表元素" << endl;
	cout << "12.初始化并用头插法(或尾插法)输入元素" << endl;
	cout << "13.实现单链表的逆序存放" << endl;
	cout << "输入一个负数,退出程序" << endl;
	int n = 1;
	while (n) {
		int select;
		cout << "------------------------------------" << endl;
		cout << "请输入你选择的功能:";
		cin >> select;
		switch (select) {
		case 1:
			if (InitList(L)) {
				initlist = true;
				cout << "链表初始化成功" << endl;
			}
			else {
				cout << "错误,链表初始化失败" << endl;
			}
			break;
		case 2:
			if (initlist == true) {
				if (DeleteList(L)) {
					initlist = false;
					cout << "链表销毁成功" << endl;
				}
			}
			else {
				cout << "请先初始化链表" << endl;
			}
			break;
		case 3:
			if (initlist == true) {
				if (ClearList(L)) {
					cout << "链表已清空" << endl;
				}
				else {
					cout << "链表为空" << endl;
				}
			}
			else {
				cout << "请先初始化链表" << endl;
			}
			break;
		case 4:
			if (initlist == true) {
				if (ListLength(L)) {
					cout << "链表长度为" << ListLength(L) << endl;
				}
				else {
					cout << "链表为空" << endl;
				}
			}
			else {
				cout << "请先初始化链表" << endl;
			}
			break;
		case 5:
			if (initlist == true) {
				if (L->next != NULL) {
					do {
						cout << "请输入你要获取元素的位置:";
						cin >> i;
						if (GetElem(L, i, e)) {
							cout << "第" << i << "个元素为:" << GetElem(L, i, e) << endl;
						}
						else {
							cout << "你要获取的位置错误" << endl;
						}
						cout << "1.继续 2.退出" << "  ";
						cin >> op;
					} while (op == 1);
				}
				else {
					cout << "链表为空" << endl;
				}
			}
			else {
				cout << "请先初始化链表" << endl;
			}
			break;
		case 6:
			if (initlist == true) {
				if (L->next != NULL) {
					do {
						int i = 1;
						cout << "请输入你要获取位置的元素:";
						cin >> e;
						if (ListLocate(L, i, e)) {
							cout << "元素" << e << "的位序是:" << i << endl;
						}
						else {
							cout << "此元素不存在" << endl;
						}
						cout << "1.继续 2.退出" << "  ";
						cin >> op;
					} while (op == 1);
				}
				else {
					cout << "链表为空" << endl;
				}
			}
			else {
				cout << "请先初始化链表" << endl;
			}
			break;
		case 7:
			if (initlist == true) {
				if (L->next != NULL) {
					cout << "请输入你要求前驱的元素:";
					cin >> e;
					i = 1;
					if (PriorList(L, e) == ERROR) {
						cout << "首元素无前驱或元素不存在" << endl;
					}
					else {
						cout << "元素" << e << "的前驱为:" << PriorList(L, e) << endl;
					}
				}
				else {
					cout << "链表为空" << endl;
				}
			}
			else {
				cout << "请先初始化链表" << endl;
			}
			break;
		case 8:
			if (initlist == true) {
				cout << "请输入你要求后继的元素:";
				cin >> e;
				if (NextList(L, e) == ERROR) {
					cout << "尾元素无后继或元素不存在" << endl;
				}
				else {
					cout << "元素" << e << "的后继为:" << NextList(L, e) << endl;
				}
			}
			else {
				cout << "请先初始化链表" << endl;
			}
			break;
		case 9:
			if (initlist == true) {
				int lo;
				do {
					int i = ListLength(L);
					cout << "请输入你要插入的位置:";
					cin >> lo;
					if (lo <= 0) {
						cout << "插入位置过小" << endl;
					}
					else if (lo > i + 1) {
						cout << "插入位置过大" << endl;
					}
					else {
						cout << "请输入你要插入的元素:";
						cin >> e;
						if (ListInsert(L, lo, e)) {
							cout << "插入成功" << endl;
						}
						else {
							cout << "插入失败" << endl;
						}
					}
					cout << "1.继续 2.退出" << "  ";
					cin >> op;
				} while (op == 1);
			}
			else {
				cout << "请先初始化链表" << endl;
			}

			break;
		case 10:
			if (initlist == true) {
				if (L->next != NULL) {
					do {
						cout << "请输入你要删除的位置:";
						cin >> i;
						if (ListDelete(L, i)) {
							cout << "删除成功" << endl;
						}
						else {
							cout << "删除位置错误" << endl;
						}
						cout << "1.继续 2.退出" << "  ";
						cin >> op;
					} while (op == 1);
				}
				else {
					cout << "链表为空" << endl;
				}
			}
			else {
				cout << "请先初始化链表" << endl;
			}
			break;
		case 11:
			if (initlist == true) {
				if (L->next != NULL) {
					OutPutList(L);
					cout << endl;
				}
				else {
					cout << "链表为空" << endl;
				}
			}
			else {
				cout << "请先初始化链表" << endl;
			}
			break;
		case 12:
		{cout << "1.初始化并用头插法输入元素" << endl;
		cout << "2.初始化并用尾插法输入元素" << endl;
		cout << "输入负数退出程序" << endl;
		cout << "请输入你的选择:";
		int i;
		cin >> op;
		switch (op) {
		case 1:
			cout << "头插法输入元素" << endl;
			cout << "请输入你要插入的元素个数:";
			cin >> i;
			cout << "请输入你要插入的元素:";
			HeadList(L, i);
			initlist = true;
			cout << endl;
			break;
		case 2:
			cout << "尾插法输入元素" << endl;
			cout << "请输入你要插入的元素个数:";
			cin >> i;
			cout << "请输入你要插入的元素:";
			TailList(L, i, e);
			initlist = true;
			cout << endl;
			break;
		default:
			if (op < 0) {
				cout << "退出程序" << endl;
			}
		}
		break;
		case 13:
			if (initlist == true) {
				if (L->next != NULL) {
					ListInverse(L);
					cout << endl;
				}
				else {
					cout << "链表为空" << endl;
				}
			}
			else {
				cout << "请先初始化链表" << endl;
			}
			break;
		default:
			if (select < 0) {
				cout << "退出程序" << endl;
				n = 0;
			}
		}
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

用户1234567890

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值