0
点赞
收藏
分享

微信扫一扫

【数据结构】实验二 实现单链表各种基本运算的算法

扒皮狼 2022-04-08 阅读 60
数据结构
#include<iostream>
using namespace std;
#define ElemType char

typedef struct LNode // 定义结构体
{
	ElemType data; // 结点的数据域
	struct LNode* next; // 结点的指针域
}LNode, * LinkList; // LNode定义头指针,*LinkList定义其他结点的指针变量

void InitList(LinkList& L) // 初始化链表
{
	L = new LNode; // 生成新结点作为头结点,并使头指针L指向头结点
	L->next = NULL; // 将头结点的指针域置空
}

void ListInsertLast(LinkList& L) // 尾插法
{
	LinkList p = L;
	while (p->next != NULL) // 将指针p遍历到链表结束
	{
		p = p->next;
	}
	cout << "请输入你要插入的元素(输入0退出):" << endl;
	ElemType x;
	while (1)
	{
		cin >> x;
		if (x == '0') // 判断是否结束尾插
			break;
		LNode* s = new LNode; // 创建一个新结点
		// 将新结点插入链表结尾
		s->data = x;
		s->next = NULL;
		p->next = s;
		p = s;
	}
}

void ListInsert(LinkList& L, int i, ElemType e) // 在链表中第 i 个位置插入一个数据元素 e
{
	LinkList p = L; // 创建一个临时指针
	int j = 0;
	while (p->next != NULL && (j < i - 1)) // 遍历链表,使指针p指向插入位置前结点
	{
		p = p->next;
		j++;
	}
	LNode* s = new LNode; // 创建一个新结点
	s->data = e;
	// 将新结点插入相应位置
	s->next = p->next;
	p->next = s;
}

void OutPutAll(LinkList& L) // 输出链表L中所有元素
{
	LinkList p = L->next; // 跳过头结点,使p指向链表的第一个元素
	cout << "链表中的元素如下:" << endl;
	while (p != NULL) // 遍历输出
	{
		cout << p->data << "\t";
		p = p->next;
	}
	cout << endl;
}

void OutLength(LinkList& L) // 输出链表L的长度
{
	LinkList p = L->next; // 跳过头结点,使p指向链表的第一个元素
	int i = 0;
	while (p != NULL) // 遍历计数
	{
		i++;
		p = p->next;
	}
	cout << "该链表的长度为:" << i << endl; // 输出线性表长度
}

void IfNull(LinkList& L) // 判断线性表是否为空
{
	if (L->next == NULL)
		cout << "该线性表为空!" << endl;
	else
		cout << "该线性表不为空!" << endl;
}

void OutPut(LinkList& L, int i) // 输出链表L的第i位元素
{
	int j = 0;
	LinkList p = L->next; // 跳过头结点,使p指向链表的第一个元素
	while (1)
	{
		if (p == NULL) // 若遍历过程中始终没有找到该元素 则输出“该线性表长度不够”
		{
			cout << "该线性表长度不够!" << endl;
			return;
		}
		if (j == i - 1) // 若在遍历完成前找到该元素 则输出
		{
			cout << "第" << i << "个元素为:" << p->data << endl;
			return;
		}
		p = p->next;
		j++;
	}
}

void LocateElem(LinkList& L, ElemType e) // 输出链表L中某元素的位置
{
	LinkList p = L->next; // 跳过头结点,使p指向链表的第一个元素
	int i = 1;
	while (p != NULL) // 遍历链表
	{
		if (p->data == e) // 查找到对应元素 并输出其位置
		{
			cout << "元素 " << e << " 在第" << i << "位。" << endl;
			return;
		}
		p = p->next;
		i++;
	}
	cout << "未查到元素" << e << endl; // 若未查到 则输出 "未查到元素"
}

void Delete(LinkList& L, int i) // 删除单链表 L 中的第 i 个元素  
{
	LinkList p = L; // 使p指向头结点
	int j = 0;
	while (p != NULL) // 遍历链表
	{
		if (j == i - 1) // 遍历到要删除的元素的位置时 删除对应元素并跳出函数
		{
			p->next = p->next->next;
			return;
		}
		p = p->next;
		j++;
	}
	cout << "该线性表长度不够!" << endl; // 若始终没有遍历到 则输出 "该线性表长度不够!"
}

void unSortList(LinkList& L) // 单链表“原地”逆转
{
	LinkList p1, p2; // 定义两个结构体指针
	p1 = L->next;
	L->next = NULL;
	while (p1 != NULL) // 不断断开结点 插入头结点与第一个数据元素之间
	{
		p2 = p1->next;
		p1->next = L->next;
		L->next = p1;
		p1 = p2;
	}
}

void ShowList() // 菜单展示
{
	cout << "***************************************" << endl;
	cout << "**     --------功能选项--------      **" << endl;
	cout << "**     1.采用尾插法连续插入元素      **" << endl;
	cout << "**     2.输出单链表                  **" << endl;
	cout << "**     3.输出单链表长度              **" << endl;
	cout << "**     4.判断单链表是否为空          **" << endl;
	cout << "**     5.输出单链表的第 i 个元素     **" << endl;
	cout << "**     6.输出某元素的位置            **" << endl;
	cout << "**     7.插入元素                    **" << endl;
	cout << "**     8.删除单链表中的第 i 个元素   **" << endl;
	cout << "**     9.单链表“原地”逆转          **" << endl;
	cout << "**     0.结束程序                    **" << endl;
	cout << "***************************************" << endl;
}

void achieve()
{
	LNode* L; // 创建一个头指针
	// 1、初始化单链表
	InitList(L); // 为头指针创建一个头结点,并使头指针指向该头结点
	int i; // 临时存储位置
	int select; // 存储选项
	ElemType e; // 临时存储数据元素
	while (1)
	{
		ShowList();
		cin >> select;
		if (select == 0)
			break;
		switch (select)
		{
		case 1:
			// 2、一次采用尾插法插入a、b、c、d、e元素
			ListInsertLast(L);
			cout << "插入后";
			OutPutAll(L);
			break;
		case 2:
			// 3、输出单链表
			OutPutAll(L);
			break;
		case 3:
			// 4、输出单链表长度
			OutLength(L);
			break;
		case 4:
			// 5、判断单链表是否为空
			IfNull(L);
			break;
		case 5:
			// 6、输出单链表的第3个元素
			cout << "请输入i:";
			cin >> i;
			OutPut(L, i);
			break;
		case 6:
			// 7、输出元素d的位置
			cout << "请输入要查找的元素:";
			cin >> e;
			LocateElem(L, e);
			break;
		case 7:
			// 8、在第4个元素位置上插入f元素
			cout << "请输入要插入的位置:";
			cin >> i;
			cout << "请输入要插入的元素:";
			cin >> e;
			ListInsert(L, i, e);
			// 9、输出插入后的单链表
			cout << "插入后";
			OutPutAll(L);
			break;
		case 8:
			// 10、删除单链表中的第2个元素
			cout << "请输入i:";
			cin >> i;
			Delete(L, i);
			// 11、输出删除后的单链表
			cout << "删除后";
			OutPutAll(L);
			break;
		case 9:
			// 12、单链表“原地”逆转,要求算法空间复杂度为O(1)
			unSortList(L);
			cout << "逆序后";
			OutPutAll(L);
			break;
		}
		system("pause"); // 暂停操作
		system("cls"); // 清屏操作
	}
}

int main()
{
	achieve();
	return 0;
}
举报

相关推荐

0 条评论