单链表的基础操作(包教包会)

//导入库包
#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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值