首页 > 其他分享 >数据结构之线性表(3)

数据结构之线性表(3)

时间:2024-06-10 12:32:07浏览次数:14  
标签:pphead 结点 NULL 线性表 next SLNode newnode 数据结构

数据结构之线性表(3)

上文我们了解了线性表的静动态存储的相关操作,此篇我们对线性表中链表的相关操作探讨。
在进行链表的相关操作时,我们先来理解单链表是什么?

1.链表的概念及结构

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
在这里插入图片描述

//单链表的结点定义
struct SeqListNode
{
	datatype data;
	struct SLNode * next;
};
typedef struct SeqListNode SLNode;

在这里插入图片描述

单链表的基本操作:

1.头插

//头插
void SLNpushfront(SLNode** pphead,datatype x)
{
	//1.不存在其他结点
	if (*pphead == NULL)
	{
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		newnode->data = x;
		newnode->next = NULL;
		*pphead = newnode;
	}
	else
	{
		//2.存在其他结点
		SLNode* tmp = (SLNode*)malloc(sizeof(SLNode));
		tmp->data = x;
		tmp->next = *pphead;
		*pphead = tmp;
	}
}

2.尾插

//尾插
void SLNpushback(SLNode** pphead, datatype x)
{
	//1.不存在其他结点
	if (*pphead == NULL)
	{
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		newnode->data = x;
		newnode->next = NULL;
		*pphead = newnode;
	}
	else
	{
		//2.存在其他结点
		SLNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		tail->next = newnode;
		newnode->data = x;
		newnode->next = NULL;
	}
}

3.头删

//头删
void SLNpopfront(SLNode** pphead)
{
	//1.链表中0个结点,无法删除
	if (*pphead == NULL)
	{
		printf("链表中没有结点,无法删除\n");
		exit(-1);
	}
	//2.链表中只有一个结点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		(*pphead) = NULL;
	}
	//3.链表中有一个以上结点
	SLNode* tmp = (*pphead)->next;
	free(*pphead);
	(*pphead) = NULL;
	*pphead = tmp;
}

4.尾删

//尾删
void SLNpopback(SLNode** pphead)
{
	//1.链表中0个结点
	if (*pphead ==NULL)
	{
		printf("链表中没有结点,无法删除\n");
		exit(-1);
	}
	//2.链表中只有一个结点,就类似于只有一个结点的头删
	if ((*pphead)->next ==NULL)
	{
		free(*pphead);
		(*pphead) = NULL;
	}
	//3.链表中有一个以上结点
	SLNode* prev = NULL;
	SLNode* tail = (*pphead);
	while (tail->next != NULL)
	{
		prev = tail;
		tail = tail->next;
	}
	free(tail);
	tail = NULL;
	prev->next = NULL;
}

5.打印

//打印
void SLNprintf(SLNode* pphead)
{
	while (pphead)
	{
		printf("%d ", pphead->data);
		pphead = pphead->next;
	}
}

6.查找

//查找
SLNode* SLNfind(SLNode* phead, datatype x)
{
	SLNode* cur = phead;
	while (cur != NULL)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

7.指定位置插入

//指定位置插入
void SLNinsert(SLNode** pphead, SLNode* pos, datatype x)
{
	if (pos == *pphead)
	{
		SLNpushfront(pphead, x);//若pos==*pphead,就等同于头插
	}
	else
	{
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		newnode->data = x;
		newnode->next = NULL;
		SLNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = newnode;
		newnode->next = pos;
	}
}

7.指定位置删除

void SLNdeleate(SLNode** pphead, SLNode* pos)
{
	if (pos == *pphead)
	{
		SLNpopfront(pphead);//若pos==*pphead,就等同于头删
	}
	else
	{
		SLNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
}

完整代码如下:

#include<stdio.h>
#include<stdlib.h>
typedef int datatype;
//单链表结点的定义
struct SeqListNode
{
	datatype data;
	struct SLNode* next;
};
typedef struct SeqListNode SLNode;
//头插
void SLNpushfront(SLNode** pphead,datatype x)
{
	//1.不存在其他结点
	if (*pphead == NULL)
	{
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		newnode->data = x;
		newnode->next = NULL;
		*pphead = newnode;
	}
	else
	{
		//2.存在其他结点
		SLNode* tmp = (SLNode*)malloc(sizeof(SLNode));
		tmp->data = x;
		tmp->next = *pphead;
		*pphead = tmp;
	}
}
//尾插
void SLNpushback(SLNode** pphead, datatype x)
{
	//1.不存在其他结点
	if (*pphead == NULL)
	{
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		newnode->data = x;
		newnode->next = NULL;
		*pphead = newnode;
	}
	else
	{
		//2.存在其他结点
		SLNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		tail->next = newnode;
		newnode->data = x;
		newnode->next = NULL;
	}
}
//头删
void SLNpopfront(SLNode** pphead)
{
	//1.0个结点,无法删除
	if (*pphead == NULL)
	{
		printf("链表中没有结点,无法删除\n");
		exit(-1);
	}
	//2.链表中只有一个结点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		(*pphead) = NULL;
	}
	//3.链表中有一个以上结点
	SLNode* tmp = (*pphead)->next;
	free(*pphead);
	(*pphead) = NULL;
	*pphead = tmp;
}
//尾删
void SLNpopback(SLNode** pphead)
{
	//1.链表中0个结点
	if (*pphead ==NULL)
	{
		printf("链表中没有结点,无法删除\n");
		exit(-1);
	}
	//2.链表中只有一个结点,就类似于只有一个结点的头删
	if ((*pphead)->next ==NULL)
	{
		free(*pphead);
		(*pphead) = NULL;
	}
	//3.链表中有一个以上结点
	SLNode* prev = NULL;
	SLNode* tail = (*pphead);
	while (tail->next != NULL)
	{
		prev = tail;
		tail = tail->next;
	}
	free(tail);
	tail = NULL;
	prev->next = NULL;
}
//打印
void SLNprintf(SLNode* pphead)
{
	while (pphead)
	{
		printf("%d ", pphead->data);
		pphead = pphead->next;
	}
}
//指定位置插入
void SLNinsert(SLNode** pphead, SLNode* pos, datatype x)
{
	if (pos == *pphead)
	{
		SLNpushfront(pphead, x);
	}
	else
	{
		SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
		newnode->data = x;
		newnode->next = NULL;
		SLNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = newnode;
		newnode->next = pos;
	}
}
//指定位置删除
void SLNdeleate(SLNode** pphead, SLNode* pos)
{
	if (pos == *pphead)
	{
		SLNpopfront(pphead);
	}
	else
	{
		SLNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
}
//查找
SLNode* SLNfind(SLNode* phead, datatype x)
{
	SLNode* cur = phead;
	while (cur != NULL)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}
int main()
{
	SLNode* plist = NULL;
	SLNpushfront(&plist, 1);
	SLNpushfront(&plist, 2);
	SLNpushfront(&plist, 3);
	SLNpushback(&plist, 4);
	SLNpushback(&plist, 5);
	SLNpushback(&plist, 6);
	SLNpushback(&plist, 7);
	SLNpopfront(&plist);
	SLNpopback(&plist);
	SLNprintf(plist);
	return 0;
}

以上就是单链表中最简单的一种结构的相关操作啦,谢谢大家支持。
在这里插入图片描述

标签:pphead,结点,NULL,线性表,next,SLNode,newnode,数据结构
From: https://blog.csdn.net/2302_81707171/article/details/139507460

相关文章

  • 线性表总结(数据结构C++,大二下写,初学者)
    这段时间,我学到了这门课的第一种数据结构——线性表。关于线性表的知识,我总结为三方面:课本上学到的知识、上机实现课本上的例子的过程所学到的知识和力扣做题学到的知识和技巧。顺序表线性表中第一个学到的是顺序表,为此我翻了一下课本。顺序表,顾名思义,是线性表的顺序存储结构......
  • 第二章、线性表
    目录一、线性表的基本概念1.定义2.线性表的一些操作(1).基本操作(增删改查)(2).线性表其他常用操作(3)在定义这些操作时的注意事项3.重要考点总结4.易错题总结二、顺序表1.顺序表定义2.顺序表实现方式3.顺序表元素的插入和删除(1)插入元素(2)删除元素4.顺序表查......
  • 【数据结构】链式二叉树详解
    个人主页~链式二叉树基本内容~链式二叉树详解1、通过前序遍历的数组来构建二叉树2、二叉树的销毁3、二叉树节点个数4、二叉树叶子节点个数5、二叉树第k层节点个数6、二叉树查找7、前序遍历8、中序遍历9、后序遍历10、层序遍历与检查二叉树是否为完全二叉树Queue.hQue......
  • 数据结构严蔚敏版精简版-线性表以及c语言代码实现
    线性表、栈、队列、串和数组都属于线性结构。线性结构的基本特点是除第一个元素无直接前驱,最后一个元素无直接后继之外,其他每个数据元素都有一个前驱和后继。1 线性表的定义和特点如此类由n(n大于等于0)个数据特性相同的元素构成的有限序列称为线性表。线性表中元素的个数n定......
  • 【数据结构·队列】链队列(带头结点)模板简单应用算法设计:长整数加法计算
    目的:使用C++模板设计链队列的抽象数据类型(ADT)。并在此基础上,使用链队列ADT的基本操作,设计并实现简单应用的算法设计。内容:(1)请参照单链表的ADT模板,设计链队列的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及......
  • Java数据结构与算法(最大子数组和动态规划)
    前言动态规划主要用于解决具有重叠子问题和最优子结构性质的问题。它通过将问题分解为子问题来解决复杂问题,每个子问题仅解决一次,并将其结果存储,以供后续使用,从而避免了重复计算。对应leetcode.-力扣(LeetCode)实现原理两次循环遍历,采用固定其实位置为i,不断滑动j的思想,来计......
  • Java数据结构与算法(爬楼梯动态规划)
    前言爬楼梯就是一个斐波那契数列问题,采用动态规划是最合适不过的。实现原理初始化:dp[0]=1;dp[1]=2;转移方程:dp[i]=dp[i-1]+d[i-2];边界条件:无具体代码实现classSolution{publicintclimbStairs(intn){if(n==1){return1;}......
  • 数据结构---树与二叉树
    个人介绍hellohello~,这里是code袁~......
  • 数据结构与算法之归并排序,以及它的代码实现与事例
    目录前言定义策略代码实现结果结束语前言今天是坚持写博客的第22天,我们来看看数据结构与算法当中的归并排序。定义首先我们来看看什么是归并排序?归并排序(MergeSort)是一种分治思想的排序算法。它将待排序的数组分成若干个子数组,每个子数组都是有序的,然后再将有序......
  • 数据结构学习笔记-堆排序
    堆排序算法的设计与分析问题描述:设计并分析堆排序【前置知识:什么是堆?】堆(Heap)是一种特殊的树形数据结构,它满足以下两个条件之一:最大堆(MaxHeap):每个节点的值都大于或等于其子节点的值。换句话说,根节点的值是整个堆中最大的。最小堆(MinHeap):每个节点的值都小于或等于其......