数据结构——考研笔记(三)线性表之单链表
创始人
2024-12-28 12:09:05
0

文章目录

      • 2.3 单链表
        • 2.3.1 知识总览
        • 2.3.2 什么是单链表
        • 2.3.3 不带头结点的单链表
        • 2.3.4 带头结点的单链表
        • 2.3.5 不带头结点 VS 带头结点
        • 2.3.6 知识回顾与重要考点
        • 2.3.7 单链表的插入和删除
          • 2.3.7.1 按位序插入(带头结点)
          • 2.3.7.2 按位序插入(不带头结点)
          • 2.3.7.3 指定结点的后插操作
          • 2.3.7.4 指定结点的前插操作
          • 2.3.7.5 按位序删除(带头结点)
          • 2.3.7.6 知识回顾与重要考点
        • 2.3.8 单链表的查找
          • 2.3.8.1 按位查找
          • 2.3.8.2 按值查找
          • 2.3.8.3 知识回顾与重要考点
        • 2.3.9 单链表的建立
          • 2.3.9.1 尾插法
          • 2.3.9.2 头插法


2.3 单链表

2.3.1 知识总览

image-20240715163504480

2.3.2 什么是单链表

image-20240715163622432

  • 顺序表

    • 优点:可随机存取,存储密度高
    • 缺点:要求大片连续空间,改变容量不方便
  • 单链表

    • 优点:不要求大片连续空间,改变容量方便
    • 缺点:不可随机存取,要消耗一定空间存放指针
  • 用代码实现单链表

image-20240715164545122

typedef struct LNode{			//定义单链表结点类型     ElemType data;		//每个节点存放一个数据元素     struct LNode* next;  //指针指向下一个节点 }LNode,*LinkList; 
2.3.3 不带头结点的单链表
#include   typedef struct LNode {	//定义单链表结点类型 	int data;			//每个节点存放一个数据元素 	struct LNode* next; //指针指向下一个节点 }LNode,*LinkList;  //初始化一个空的单链表 bool InitList(LinkList& L) { 	L = NULL;	//空表,暂时还没有任何结点 	return true; }  //判断单链表是否为空 bool Empty(LinkList L) { 	if (L == NULL) 		return true; 	else 		return false; }  void test() { 	LinkList L;	//声明一个指向单链表的指针 	//初始化一个空表 	InitList(L); 	//……后续代码…… } 
2.3.4 带头结点的单链表

image-20240715171402035

#include   typedef struct LNode {	//定义单链表结点类型 	int data;			//每个节点存放一个数据元素 	struct LNode* next; //指针指向下一个节点 }LNode, * LinkList;  //初始化一个空的单链表 bool InitList(LinkList& L) { 	L = (LNode*)malloc(sizeof(LNode));	//分配一个头节点 	if (L == NULL)			//内存不足,分配失败 		return false; 	L->next = NULL;			//头结点之后暂时还没有节点 	return true; }  //判断单链表是否为空 bool Empty(LinkList L) { 	if (L->next == NULL) 		return true; 	else 		return false; }  void test() { 	LinkList L;	//声明一个指向单链表的指针 	//初始化一个空表 	InitList(L); 	//……后续代码…… } 
2.3.5 不带头结点 VS 带头结点

image-20240715171704621

  • 不带头结点:写代码更麻烦对第一个数据结点和后续数据结点的处理需要用不同的代码逻辑对空表和非空表的处理需要用到不同的代码逻辑
  • 带头结点:写代码更方便。
2.3.6 知识回顾与重要考点

image-20240715171817961

2.3.7 单链表的插入和删除

image-20240715172017835

2.3.7.1 按位序插入(带头结点)
  • ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。

image-20240715172337653

  • 代码展示

image-20240715174709999

#include   typedef struct LNode {	//定义单链表结点类型 	int data;			//每个节点存放一个数据元素 	struct LNode* next; //指针指向下一个节点 }LNode, * LinkList;  //初始化一个空的单链表 bool InitList(LinkList& L) { 	L = (LNode*)malloc(sizeof(LNode));	//分配一个头节点 	if (L == NULL)			//内存不足,分配失败 		return false; 	L->next = NULL;			//头结点之后暂时还没有节点 	return true; }  //判断单链表是否为空 bool Empty(LinkList L) { 	if (L == NULL) 		return true; 	else 		return false; }  //在第i个位置插入元素e(带头结点) bool ListInsert(LinkList& L, int i, int e) { 	if (i < 1) 		return false; 	LNode* p;	//指针p指向当前扫描到的结点 	int j = 0;	//当前p指向的是第几个结点 	p = L;		//L指向头结点,头结点是第0个结点(不存数据) 	while (p != NULL && j < i - 1) {	//循环找到第i-1个结点 		p = p->next; 		j++; 	} 	if (p == NULL)	//i值不合法 		return false; 	LNode* s = (LNode*)malloc(sizeof(LNode)); 	s->data = e; 	s->next = p->next; 	p->next = s;	//将结点s连到p之后 	return true;	//插入成功 }  void main() { 	LinkList L;	//声明一个指向单链表的指针 	//初始化一个空表 	InitList(L); 	//……后续代码…… } 
2.3.7.2 按位序插入(不带头结点)

image-20240715175632081

  • 代码展示
#include   typedef struct LNode {	//定义单链表结点类型 	int data;			//每个节点存放一个数据元素 	struct LNode* next; //指针指向下一个节点 }LNode, * LinkList;  //初始化一个空的单链表 bool InitList(LinkList& L) { 	L = (LNode*)malloc(sizeof(LNode));	//分配一个头节点 	if (L == NULL)			//内存不足,分配失败 		return false; 	L->next = NULL;			//头结点之后暂时还没有节点 	return true; }  //判断单链表是否为空 bool Empty(LinkList L) { 	if (L == NULL) 		return true; 	else 		return false; }  //在第i个位置插入元素e(带头结点) bool ListInsert(LinkList& L, int i, int e) { 	if (i < 1) 		return false; 	if (i = 1) {	//插入第1个结点的操作与其它结点的操作不同 		LNode* s = (LNode*)malloc(sizeof(LNode)); 		s->data = e; 		s->next = L; 		L = s;		//头指针指向新节点 		return true; 	} 	LNode* p;	//指针p指向当前扫描到的结点 	int j = 1;	//当前p指向的是第几个结点 	p = L;		//L指向头结点,头结点是第0个结点(不存数据) 	while (p != NULL && j < i - 1) {	//循环找到第i-1个结点 		p = p->next; 		j++; 	} 	if (p == NULL)	//i值不合法 		return false; 	LNode* s = (LNode*)malloc(sizeof(LNode)); 	s->data = e; 	s->next = p->next; 	p->next = s;	//将结点s连到p之后 	return true;	//插入成功 }  void main() { 	LinkList L;	//声明一个指向单链表的指针 	//初始化一个空表 	InitList(L); 	//……后续代码…… } 
2.3.7.3 指定结点的后插操作

image-20240715180832621

//后插操作:在p结点之后插入元素e bool InsertNextNode(LNode* p, int e) { 	if (p == NULL) 		return false; 	LNode* s = (LNode*)malloc(sizeof(LNode)); 	if (s == NULL)	//内存分配失败 		return false; 	s->data = e;	//用结点s保存数据元素e 	s->next = p->next; 	p->next = s;	//将结点s连到p之后 	return true; } 
2.3.7.4 指定结点的前插操作

image-20240715181828300

  • 代码展示
//前插操作:在p结点之前插入元素e bool InsertPriorNode(LNode* p, int e) { 	if (p == NULL)		//内存分配失败 		return false; 	LNode* s = (LNode*)malloc(sizeof(LNode)); 	s->next = p->next; 	p->next = s;		//新结点s连到p之后 	s->data = p->data;	//将p中元素复制到s中 	p->data = e;		//p中元素覆盖为e 	return true; }  
2.3.7.5 按位序删除(带头结点)
  • ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。

image-20240715183805791

  • 代码展示
//删除表中第i个元素 bool ListDelete(LinkList& L, int i, int& e) { 	if (i < 1) 		return false; 	LNode* p;		//指针p指向当前扫描到的结点 	int j = 0;		//当前p指向的是第几个结点 	p = L;			//L指向头结点,头结点是第0个结点(不存数据) 	while (p != NULL && j < i - 1) {	//循环找到第i-1个结点 		p = p->next; 		j++; 	} 	if (p == NULL)	//i值不合法 		return false; 	if (p->next == NULL)	//第i-1个结点之后无其他结点 		return false; 	LNode* q = p->next;		//令q指向被删除结点 	e = q->data;			//用e返回元素的值 	p->next = q->next;		//将*q结点从链中“断开” 	free(q);				//释放结点的存储空间 	return true;			//删除成功 } 
2.3.7.6 知识回顾与重要考点

image-20240715190156270

2.3.8 单链表的查找

image-20240715190606364

  • GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。
  • LocalteElem(L,e):按值查找。在表L中查找具有给定关键字值的元素。
2.3.8.1 按位查找
  • 代码展示
//按位查找,返回第i个元素(带头结点) LNode* GetElem(LinkList L, int i) { 	if (i < 0) 		return false; 	LNode* p;		//指针p指向当前扫描到的结点 	int j = 0;		//当前p指向的是第几个结点 	p = L;			//L指向头节点,头结点是第0个结点(不存数据) 	while (p != NULL && j < i) {	//循环找到第i个结点 		p = p->next; 		j++; 	} 	return p; } 
2.3.8.2 按值查找
  • 代码展示
//按值查找,找到数据域==e的结点 LNode* LocateElem(LinkList L, int e) { 	LNode* p = L->next; 	//从第1个结点开始查找数据域为e的结点 	while (p != NULL && p->data != e) 		p = p->next; 	return p;	//找到后返回该结点指针,否则返回NULL } 
2.3.8.3 知识回顾与重要考点

image-20240715192241414

2.3.9 单链表的建立

image-20240715192343150

如果给你很多个数据元素(ElemType),要把它们存到一个单链表里边,怎么办呢?

step1:初始化一个单链表

step2:每次取一个数据元素,插入到表尾/表头

2.3.9.1 尾插法
  • 代码展示
//尾插法 LinkList List_TailInsert(LinkList& L) {	//正向建立单链表 	int x;								 	L = (LinkList)malloc(sizeof(LNode));//建立头结点 	LNode* s, * r = L;					//r为表尾指针 	scanf("%d", &x);					//输入结点的值 	while (x != 9999) {					//输入9999表示结束 		s = (LNode*)malloc(sizeof(LNode)); 		s->data = x; 		r->next = s; 		r = s;							//r指向新的表尾结点 		scanf("%d", &x); 	} 	r->next = NULL;						//尾结点指针置空 	return L; } 
2.3.9.2 头插法
  • 代码展示
//头插法 LinkList List_HeadInsert(LinkList& L) { 	LNode* s; 	int x; 	L = (LNode*)malloc(sizeof(LNode));	//建立头结点 	L->next = NULL;						//初始化空链表 	scanf_s("%d", &x);					//输入结点的值 	while (x != 9999) {					//输入9999表示结束 		s = (LNode*)malloc(sizeof(LNode));//创建新结点 		s->data = x; 		s->next = L->next; 		L->next = s;					//将新结点插入表中,L为头指针 		scanf_s("%d", &x); 	} 	return L; } 

相关内容

热门资讯

第七妙招!蛮王大厅辅助,微信微... 大家好,今天小编来为大家解答微信微乐辅助器下载这个问题咨询软件客服可以免费测试直接加微信(13670...
科普常识!广东潮汕雀友会插件,... 您好:这款广东潮汕雀友会插件游戏是可以开挂的,确实是有挂的,很多玩家在这款广东潮汕雀友会插件游戏中打...
透视好友房!财神十三章辅助真的... 透视好友房!财神十三章辅助真的假的,雀友会广东潮汕麻将辅助软件,AI教程(有挂教学);无需打开直接搜...
第二分钟辅助挂!微信小程序游戏... 第二分钟辅助挂!微信小程序游戏破解器,瓜瓜丰城双剑旧版攻略(体悟透视开挂辅助器);打开点击测试直接进...
第十绝活!广东雀神智能插件安装... 第十绝活!广东雀神智能插件安装辅助器,广东雀神挂机怎么样(有挂开挂辅助插件) 了解更多开挂安装加(1...
我来教教你!山西扣点有没有辅助... 我来教教你!山西扣点有没有辅助器,微友辅助器免费版(有挂存在辅助开挂平台);无需打开直接搜索微信(1...
透视软件!xpoker透视辅助... xpoker透视辅助开挂教程视频分享装挂详细步骤在当今的网络游戏中,xpoker透视辅助作为一种经典...
1分钟辅助挂!小逸碰胡脚本,牵... 1分钟辅助挂!小逸碰胡脚本,牵手游戏辅助(理解开挂透视辅助安装)这是一款可以让一直输的玩家,快速成为...
五教材!九酷众游辅助,微乐自建... 五教材!九酷众游辅助,微乐自建房辅助工具2025在哪(有挂开挂辅助软件);无需打开直接搜索加薇136...
玩家必看!微信呢小程序辅助器,... 【亲,微信呢小程序辅助器 这款游戏可以开挂的,确实是有挂的,很多玩家在这款微信呢小程序辅助器中打牌都...