//导入库包
#include<iostream>
#include<algorithm>
#include<stdlib.h>
using namespace std;
//宏定义
#define true 1
#define false 0
//重命名类型名
typedef int status;
typedef int elementtype;
//【1】单链表的数据结构定义
typedef struct LNode {
elementtype data; //数据域
struct LNode* next; //指针域
}LNodo, * LinkList; //LNode 即是struct LNode , LinkList 即是 struct LNode*
//【2】初始化单链表
LinkList InitLinkList() {
LinkList L = (LNode*)malloc(sizeof(LNode)); //分配空间
L->data = 0; //L的数据域即是单链表的长度
L->next = NULL; //开始链表为空
return L;
}
//【3】打印单链表
void PrintLinkList(LinkList L) {
LinkList p = L->next; //指向单链表的第一个节点
cout << "打印链表为" << endl;
while (p) {
cout << p->data << "-->";
p = p->next; //后移p
}
cout << "NULL" << endl;
cout << "该链表的长度是 " << L->data;
cout << endl;
}
//【4】使用头插法插入元素
status Insertelementbyhead(LinkList L, int num) {
cout << "你将用头插法插入" << num << "个元素" << endl;
cout << "请依次输入" << endl;
elementtype e; //定义要插入的元素的变量名
LinkList NewNode; //新增节点名字
for (int i = 0; i < num; i++) { //一个循环 循环num次 输入num个元素
cin >> e; //输入e
NewNode = (LinkList)malloc(sizeof(LNode)); //为新增的节点申请空间
NewNode->data = e; //新增节点数据域赋值
NewNode->next = L->next; //让新增节点的下一个节点成为 原来的第一个节点(头节点的下一个节点)
L->next = NewNode; //使头节点的下一个节点成为新增节点
L->data++; //链表长度增加
}
PrintLinkList(L); //展示插入后的链表
return true;
}
//【5】使用尾插法插入元素
status Insertelementbytail(LinkList L, int num) {
cout << "你将用尾插法插入 " << num << "个元素" << endl;
cout << "请依次输入" << endl;
LinkList Tail = L, NewNode; //定义尾节点 新增节点名
elementtype e; //定义要插入的元素的变量名
while (Tail->next) { //链表不像数组一样 , 我们得找到尾结点具体的地址 这里是从头结点开始找找到尾结点(尾节点的下一节点为NULL) 或者可以从第一个节点开始找Tail = L.next 循环条件是 p!=NULL
Tail = Tail->next;
}
for (int i = 0; i < num; i++) { //循环num次 输入num个元素
cin >> e;
NewNode = (LinkList)malloc(sizeof(LNode)); //为新增节点开辟空间
NewNode->data = e; //新增节点数据域赋值
NewNode->next = NULL; //新增节点成为最后一个节点 (新增节点的next为空)
Tail->next = NewNode; //尾结点的下一个节点是新增节点
Tail = NewNode; //现在新增节点是最后一个节点 即新增节点是新的尾结点
L->data++; //链表长度增加
}
PrintLinkList(L); //展示插入后的链表
return 0;
}
//【6】 按位查找 函数一(会返回查找值)
LNode* Findelementbysite(LinkList L, int site, elementtype& e) {
if (site == 0) {
cout << "你输入的是0 将返回链表的长度" << L->data;
return L;
}
if (site<1 || site>L->data) {
cout << "链表的长度为 " << L->data << endl << "你要查找的位置错误 将返回NULL" << endl;
return NULL;
}
int i = 0;
LinkList p = L;
while (p->next != NULL && i < site) { //等p不为空并且还没到site 循环才进行
p = p->next;
i++;
}
if (i == site) { //找到site了
cout << "你要找的元素已经找到 值为" << p->data << endl;
return p;
}
}
//函数二(不会返回查找值) 在插入删除函数中使用
LNode* Findelementbysite(LinkList L, int site) { //判断site是否合理的查找在插入删除函数中执行
if (site == 0) return L;
int i = 0;
LinkList p = L;
while (p->next != NULL && i < site) {
p = p->next;
i++;
}
if (i == site) return p;
}
//【7】按位查找
LNode* Findelementbyvalue(LinkList L, elementtype value) {
if (!L->data) {
cout << "这是一个空表" << endl;
return NULL;
}
LinkList p = L->next;
int site = 0;
while (p) {
site++;
if (p->data == value) {
cout << "你要找的元素已经找到 位置在" << site << "号" << endl;
return p;
}
p = p->next;
}
cout << "表中无此元素" << endl;
return NULL;
}
//【8】按位插入操作
status insertelementbysite(LinkList L, int site, elementtype e) {
if (site<1 || site - 1>L->data) { //判断site是否合理 可以在链表的后一位插入 如链表长度为5 可以插入在第6个位置
cout << "输入的位置不合法" << endl;
return false;
}
LinkList p = Findelementbysite(L, site - 1), NewNode = (LinkList)malloc(sizeof(LNode)); // p为site的前一个元素 用按位查找的到其结果 为新增节点申请空间
NewNode->data = e; //为新增节点的数据域赋值
NewNode->next = p->next; //把新增节点的下一个节点指向原来的site节点(p节点的下一个)
p->next = NewNode; //p节点的下一个节点变为新增节点(p节点为site节点的上一个)
L->data++; //链表长度+1
PrintLinkList(L); //打印插入后的链表
return true;
}
//【9】按位删除操作
status deleteelementbysite(LinkList L, int site) {
if (L->next == NULL) {
cout << "空表无法操作" << endl;
return false;
}
if (site<1 || site>L->data) { //只可以删除1到length个节点
cout << "输入的位置不合法";
return false;
}
LinkList p, s;
p = Findelementbysite(L, site - 1); //找到site节点的前一个节点
s = p->next; //s节点即为要删除的节点
cout << "删除位置的元素是 " << s->data << endl;
p->next = s->next; //将p的下一个节点修改为s的下一个节点(跳过s节点)
free(s); //释放s的空间
L->data--; //链表的长度-1
PrintLinkList(L);
return true;
}
//【10】销毁链表
status DestoryLinkList(LinkList L) {
//从第一个节点开始
while (L->data) { //遍历链表删除其值释放其空间
deleteelementbysite(L, 1);
}
cout << "链表销毁成功" << endl;
free(L); //释放头结点的空间
return true;
}
int main() {
int key = 0;
int lenght = 0;
elementtype e = 0;
LinkList L = InitLinkList();
while (1) {
system("cls");
cout << "---------------------------------------------------单链表的基础操作------------------------------------------------" << endl;
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 << "你要进行什么操作" << endl;
cin >> key;
if (key == 8) {
DestoryLinkList(L);
break;
}
else if (key == 1) {
PrintLinkList(L);
}
else if (key == 2) {
cout << "你要插入几个元素" << endl;
cin >> lenght;
Insertelementbyhead(L, lenght);
}
else if (key == 3) {
cout << "你要插入几个元素" << endl;
cin >> lenght;
Insertelementbytail(L, lenght);
}
else if (key == 4) {
cout << "你要查找的元素在第几位" << endl;
cin >> lenght;
Findelementbysite(L, lenght, e);
}
else if (key == 5) {
cout << "你要查找的元素的值是" << endl;
cin >> e;
Findelementbyvalue(L, e);
}
else if (key == 6) {
cout << "你要插入的元素是" << endl;
cin >> e;
cout << "你要插入到第几位" << endl;
cin >> lenght;
insertelementbysite(L, lenght, e);
}
else if (key == 7) {
cout << "你要删除的元素在第几位" << endl;
cin >> lenght;
deleteelementbysite(L, lenght);
}
else {
cout << "输入错误请你重新输入" << endl;
continue;
}
system("pause");
}
return 0;
}
单链表的基础操作(包教包会)
最新推荐文章于 2024-07-21 22:06:29 发布