链表的基础知识

单链表基础知识整理 单链表知识整理 基础:顺序存储结构与链式存储结构 删除链表结点 链表反转 快慢指针法解决链表相关问题 顺序存储结构与链式存储结构 (首先需要理解线性表的概念) 顺序存储结构 链式存储结构 用一段连续的存储单元存放线性表的数据元素,即逻辑上相邻的,空间上也相邻。 用一组任意的存储单元存放线性表的数据元素,即逻辑上相邻的,空间上不一定相邻。 需要预分配存储空间 不需要预分配存储空间 ... 阅读详情
//链表基础知识


typedef int DataType;


typedef struct ListNode
{
struct ListNode* _pNext;
DataType _data;
}ListNode,*PNode;


// 链表的初始化 
void SListInit(PNode* pHead);


//创建新结点
PNode BuyNewNode(DataType data);




// 尾插 
void SListPushBack(PNode* pHead, DataType data);


// 尾删 
void SListPopBack(PNode* pHead);


// 头插 
void SListPushFront(PNode* pHead, DataType data);


// 头删 
void SListPopFront(PNode* pHead);


// 在链表中查找值为data的元素,找到后返回值为data的结点 
PNode SListFind(PNode pHead, DataType data);


//求链表结点个数
int SListSize(PNode phead);


// 在pos位置插入值为data的结点 
void SListInsert(PNode* pHead, int pos, DataType data);


// 删除pos位置的结点 
void SListErase(PNode* pHead, int pos);


// 获取链表中值data的结点 
int SListDataSize(PNode pHead,DataType data);


// 判断链表是否为空 
int SListEmpty(PNode pHead);


// 销毁链表 
void SListDestroy(PNode* pHead);




///////////////////////////////////////////////////////////////


//测试函数


void testSListInit();  //测试初始化


void testPushTail();     //测试尾插


void testSListPopBack();       //测试尾删


void testPushFront();        //测试头插


void testPopFront();           //测试头删


void testFind();      //测试找到值为data的结点,返回结点




void testInsert();        //测试在pos位置插入data


void testErase();     //测试删除pos位置结点




void testDataSize();          //测试获取值为data的结点


void testEmptyAndDestory();         ////测试摧毁链表和判断链表是否为空




// 链表的初始化 
void SListInit(PNode* pHead)
{
assert(pHead);


*pHead = NULL;          //将结点赋空

}


//创建新结点
PNode BuyNewNode(DataType data)
{
PNode pNew = NULL;


pNew = (PNode)malloc(sizeof(PNode));   //申请一块新结点的空间


if (NULL == pNew)                      //判断是否申请成功
{
printf("申请结点失败!!\n");
return NULL;
}


pNew->_data = data;
pNew->_pNext = NULL;
return pNew;


}


// 尾插 
void SListPushBack(PNode* pHead, DataType data)
{
assert(pHead);


PNode pCur;
PNode tail = BuyNewNode(data);             //创建新结点
pCur = *pHead;


if (NULL == pCur)                          // 判断头结点是否为空
{
*pHead = tail;
}


else{
while (pCur->_pNext)                      // 遍历链表 找到最后一个结点
{
pCur = pCur->_pNext;
}
pCur->_pNext = tail;                       //将最后结点的下一个结点改为新结点
}


}


// 尾删 
void SListPopBack(PNode* pHead)
{
assert(pHead);


PNode pCur = NULL;
PNode pDel = NULL;
pCur = *pHead;
pDel = pCur->_pNext;


if (NULL == *pHead)        //判断链表是否为空
return;

else if (pCur->_pNext == NULL)    //只有一个结点  直接令其为空
{
*pHead = NULL;
}
else
{
while (pDel->_pNext)            //遍历链表,找到最后结点
{
pCur = pDel;
pDel = pDel->_pNext;
}
}
//free(pDel);                          //防止野指针的产生
pCur->_pNext = NULL;              // 让最后一个结点为空


}


// 头插 
void SListPushFront(PNode* pHead, DataType data)
{
assert(pHead);


PNode pNewHead;
PNode pCur;
pCur = *pHead;
pNewHead = BuyNewNode(data);             //创建新结点


if (NULL == *pHead)
{
*pHead = pNewHead;                   //空链表,直接将新结点赋给原结点
}


else
{
DataType tem;
pNewHead->_pNext = pCur->_pNext;         //先将new与后面链接
pCur->_pNext = pNewHead;                //使phead下一个结点指向新结点
tem = pNewHead->_data;                   //交换两个结点的data
pNewHead->_data = pCur->_data;
pCur->_data = tem;
}
}


// 头删 
void SListPopFront(PNode* pHead)
{
assert(pHead);
PNode pCur;
PNode pDel;
pCur = *pHead;


if (NULL == *pHead)           //处理头结点
return;


else if (NULL == pCur->_pNext)     //处理 只有一个结点
{
*pHead = NULL;
}
else                          //处理多个结点
{
pDel = pCur->_pNext;
DataType tem = pCur->_data;
pCur->_data = pDel->_data;     
pDel->_data = tem;                   //交换data 删除第二个结点,   相当于删除第一个结点
pCur->_pNext = pDel->_pNext;
free(pDel);                 //释放删除后的结点


}
}


// 在链表中查找值为data的元素,找到后返回值为data的结点 
PNode SListFind(PNode pHead, DataType data)
{
//assert(pHead);


PNode pCur;
pCur = pHead;


if (pHead == NULL)                //处理空链表
{
return NULL;
}
else
{
while (pCur->_pNext)            //遍历链表
{
if (pCur->_data == data)
{
return pCur;                //找到值为data的结点  并返回
}
pCur = pCur->_pNext;
}
return NULL;                //没找到值为data的结点  返回空
}
}




//求链表结点个数
int SListSize(PNode phead)
{


PNode pCur;
int flag = 0;
pCur = phead;


while (pCur)
{
pCur = pCur->_pNext;
flag++;
}


return flag;
}


// 在pos位置插入值为data的结点 
void SListInsert(PNode* pHead, int pos, DataType data)
{
assert(pHead);


PNode pCur;
PNode pNew;
int size = 0;


pNew = BuyNewNode(data);
pCur = *pHead;
size = SListSize(*pHead);


if (size == 0)                  //处理空链表
{
return;
}
else
{
while (--pos && pCur)         //遍历链表  找到pos位置或者pcur为null
{
pCur = pCur->_pNext;
}
if (pCur == NULL)            //处理pcur为空
{
return;
}
else                       // 找到pos位置,插入到pcur后面,再交换二者数据
{
pNew->_pNext = pCur->_pNext;
pCur->_pNext = pNew;
int tem = 0;
tem = pNew->_data;
pNew->_data = pCur->_data;
pCur->_data = tem;
}
}
}


// 删除pos位置的结点 
void SListErase(PNode* pHead, int pos)
{
assert(pHead);


PNode pCur;
PNode pDel = NULL;
int size;


pCur = *pHead; 
size = SListSize(*pHead);


if (size == 0)
{
return;
}
while (--pos && pCur)
{
pCur = pCur->_pNext;
}
if (pCur == NULL)
{
return;
}
else
{
pDel = pCur->_pNext;
if (pDel == NULL)
{
SListPopBack(pHead);
}
else
{
pCur->_pNext = pDel->_pNext;
pCur->_data = pDel->_data;
//free(pDel);
}
}
}


// 获取链表中值data的结点 
int SListDataSize(PNode pHead, DataType data)
{
PNode pCur;
int count = 0;


pCur = pHead;


if (pHead == NULL)            //测试空链表
{
return -1;
}
else
{
while (pCur->_data != data)            //找到data  或者  遍历完链表后跳出循环
{
pCur = pCur->_pNext;
count++;
if (pCur == NULL)
{
return -1;
}
}
}
return count + 1;                    //返回data处在第几个结点
}


// 判断链表是否为空 
int SListEmpty(PNode pHead)
{
if (pHead == NULL)
return 0;
else 
return 1;
}


// 销毁链表 
void SListDestroy(PNode* pHead)
{
assert(pHead);


PNode pCur;
pCur = *pHead;


if (*pHead == NULL)
return;
else if (pCur->_pNext == NULL)
{
free(pCur);
}
else
{
pCur = pCur->_pNext;
SListDestroy(&pCur);
}
}
////////////////////////////////////////////////////////


//测试初始化


void testSListInit()
{
PNode  pHead;



SListInit(&pHead);


}


//测试尾插


void testPushTail()
{
PNode phead;
SListInit(&phead);


SListPushBack(&phead, 5);


}


//测试尾删
void testSListPopBack()
{
PNode pHead;
SListInit(&pHead);


SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);


SListPopBack(&pHead);
}


//测试头插
void testPushFront()
{
PNode pHead;


SListInit(&pHead);


SListPushFront(&pHead, 1);


SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);


SListPushFront(&pHead, 0);
}


//测试头删
void testPopFront()
{
PNode pHead;


SListInit(&pHead);


SListPopFront(&pHead);          //测试空链表头删


SListPushBack(&pHead, 1);


SListPopFront(&pHead);          //测试只有一个结点头删


SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);


SListPushFront(&pHead, 1);         //头插


SListPopFront(&pHead);         // 测试多个结点头删


SListPushBack(&pHead, 4);


}


//测试找到值为data的结点,返回结点
void testFind()
{
PNode pHead;
PNode pFind;


SListInit(&pHead);
SListInit(&pFind);


pFind = SListFind(pHead, 1);           //测试空链表


SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);


pFind = SListFind(pHead, 2);          // 测试找到data


pFind = SListFind(pHead, 5);          //测试没找到data 
}


//测试在pos位置插入data


void testInsert()
{
PNode pHead;


SListInit(&pHead);


SListInsert(&pHead, 2, 1);       //测试空链表


SListPushBack(&pHead, 0);
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);


SListInsert(&pHead, 6, 5);      //测试pos大于结点个数


SListInsert(&pHead, 3, 9);    //测试pos小于结点个数


}


//测试删除pos位置结点
void testErase()
{
PNode pHead;


SListInit(&pHead);


SListErase(&pHead, 2);             //测试空链表


SListPushBack(&pHead, 0);
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);


SListErase(&pHead, 4);           //测试删除最后一个结点


SListErase(&pHead, 5);           //pos 大于 结点个数


SListErase(&pHead, 2);         //  pos小于 结点个数
}


//测试获取值为data的结点


void testDataSize()
{
PNode pHead;


SListInit(&pHead);


SListDataSize(pHead, 2);           // 空链表


SListPushBack(&pHead, 0);
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);


SListDataSize(pHead, 5);            //没data 值


SListDataSize(pHead, 3);             //有data值
}




//测试摧毁链表和判断链表是否为空
void testEmptyAndDestory()
{
PNode pHead;


SListInit(&pHead);


SListEmpty(pHead);


SListPushBack(&pHead, 0);
SListPushBack(&pHead, 0);
SListPushBack(&pHead, 0);


SListEmpty(pHead);


SListDestroy(&pHead);
}

OPC UA 服务端的模拟工具及客户端工具 详细介绍如何使用 Prosys OPC UA Simulation Server 作为 OPC UA 服务端的模拟工具来生成数据模型,并使用 Softing OPC UA Client 作为客户端工具,直观地查看和验证模拟生成的数据。 阅读详情

相关推荐

深入解析磁盘性能测试:vdbench与fio的实战对比

本文深入对比了磁盘性能测试两大工具vdbench与fio的核心定位与实战应用。vdbench擅长多客户端、可编排的存储系统集成测试,而fio则以灵活的单机深度定制见长,是测试硬件极限和模拟特定应用IO模型的利器。文章通过安装指南、参数解析和典型场景对比,帮助读者根据需求选择合适工具,精准评估磁盘性能。

weixin_29300931的博客 326

链表基础知识总结

什么是链表 链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点都包括两部分:一是数据域,用来存储元素数值数据,另一个是存储直接后继结点地址的指针域,该指针一般称为next,用来指向下一个结点的位置。由于下一个结点也是链表类型,所以next的指针也要定义为链表类型。 链表中的一些基本定义和特点 头指针:是指向链表中第一个结点的指针 首元结点:是指链表中存储的第一个数据元素的结

闲适_ 1万+

南邮 2024 软件安全 实验四 自动脱壳+手动脱壳

这次这个实验很简单,就是一个简单的脱壳,然后进行爆破就行了,解法非常的多这里不多讲,会简单讲一下特殊情况这个点开是这样子:然后放进peid里面查看,我这个是原版的PEid,所以显示出来是这样:会显示nothing found,但其实如果你使用吾爱破解的魔改过的peid,它就会显示具体的壳名:然后你点击右下角的那个箭头,里面会有很多的插件用来自动脱壳:你也可以使用这个通用脱壳器,但是脱壳后的程序无法运行,这个放到后面讲。

ARbing_an的博客 2561

线性结构-链表

在链表中,通常会添加一个不存储数据的节点,就是空节点,作为链表的第一个节点,之后的元素节 点,从第二个开始,操作链表就不会操作到第一个节点,方便链表的操作。除此之外还有循环链表,其差别是其最后一个元素指向的是头节点。数据元素之间的位置是任意(需要有这个元素才创建申请空间),在一个数据元素中由两部分构成,数据。关系:通过指针元素来表示,存储下一个数据元素的地址。第一个数据节点,存储数据的元素节点,叫做首元素节点。链表的一个数据元素就叫做一个节点(数据、关系)关系:前一个元素的地址,以及后一个元素的地址。...

m0_51274562的博客 1039

RapidScada在windows下的安装(详细)

1.下载地址:RapidScada官网 2.版本说明 有Linux版本和Windows版本,看自己的需求下载,推荐下载最新稳定版本。 3.系统要求 4.安装前的准备(windows10) 首先打开Windows功能: 先关闭 Microsoft .NET Framework3.5的 Windows Communication Foundation 子组件。如下图: Microsoft .NET Framework配置按下图勾选: iis安装的功能: 5.安装 解压..

m0_51275803的博客 4263

景观格局指数计算方法及代表的生态学意义(待补充)

景观指数 斑块密度(PD) 斑块密度(PD)表现某种斑块在景观中的密度,可反映出景观整体的异质性与破碎度[17],公式为PD=NP/A(1)式中NP———斑块数量,个A———景观或斑块的总面积,hm2PD———斑块密度,个/hm2 最大斑块指数(LPI) 最大斑块指数(LPI)用于确定景观中的优势斑块类型,间接反映人类活动干扰的方向和大小,公式为LPI=amaxA×100%(0≤LPI≤100%)(2)式中amax———景观或某一种斑块类型中最大斑块的面积,hm2LPI———最大斑块指数,% 凝聚

soderayer的博客 13万+

链表基础知识详解(非常详细简单易懂)

链表作为C语言中一种基础的数据结构,在平时写程序的时候用的并不多,但在操作系统里面使用的非常多。不管是RTOS还是Linux等使用非常广泛,所以必须要搞懂链表,链表分为单向链表和双向链表,单向链表很少用,使用最多的还是双向链表。单向链表懂了双向链表自然就会了。

酒无忧的博客 1839

vivado2025安装教程:手把手带你完成环境配置

详细讲解vivado2025的安装步骤与环境配置技巧,帮助开发者快速搭建FPGA开发平台。涵盖常见问题解决方案,确保vivado2025稳定运行,提升开发效率。

weixin_42588672的博客 3021

链表知识点总结

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。每一个结构均含有元素和指向该元素后继结构的指针。

Lookdrama的博客 1407

STM32CubeMX配置FSMC驱动外部SRAM全流程详解

FSMC(灵活静态存储控制器)是STM32实现高速并行外部存储扩展的核心外设,其本质是将片外SRAM地址空间映射为CPU可直接读写的内存区域。原理上依赖于精确的时序寄存器配置(如BTRx)、GPIO复用功能启用及AHB3总线时钟同步机制,技术价值在于免DMA搬运的零拷贝访问能力与确定性低延迟。典型应用场景包括工业HMI缓存、医疗设备实时数据采集、嵌入式图形加速等对带宽和确定性要求严苛的系统。本文围绕STM32F407ZG平台,结合STM32CubeMX工程化配置、硬件信号完整性设计与HAL库底层映射逻辑,系

weixin_34718952的博客 232

什么是 SAP PCE?

SAP Private Cloud Edition 是一种基于云计算的部署模式,它结合了公有云的灵活性和私有云的安全性,为企业提供了量身定制的云服务。在 PCE 环境中,SAP 托管和维护客户的应用系统(如 SAP S/4HANA、SAP SuccessFactors 或 SAP BW/4HANA),同时客户拥有更高的定制化权限。专属环境:每个客户在云中拥有独立的资源,这保障了更高的安全性和性能。全面托管:SAP 提供基础架构、系统管理和更新服务,降低了客户的运维成本。灵活扩展。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2246

数据结构与算法基础-----链表的结点

单链表: 结点只有一个指针域的链表 双链表: 结点有两个指针域的链表 循环链表: 首尾相接的链表 头指针、头节点、首元结点: 头指针:指向链表中第一个结点的指针 头结点:是在链表首元结点之前附设的一个结点,并不是链表的第一个结点 首元结点:是指链表中存储第一个数据元素的结点 一、如何表示空表? 无头结点时,头指针为空表示空表。 有头结点时,头结点的指针域为空表示空表 二、在链表...

lhyhaiyan的博客 6123

纳米尺度仿真软件:GROMACS_(3).分子动力学模拟原理

分子动力学(MD)模拟是一种强大的计算方法,通过数值积分牛顿运动方程,追踪粒子在时间上的位置和速度变化,提供关于体系动力学行为的详细信息。选择合适的力场、设置初始条件、应用边界条件、控制温度和压力、选择合适的时间步长、计算能量和力,是 MD 模拟的关键步骤。通过这些步骤,可以对各种化学、生物和材料体系进行模拟和分析,揭示其结构、动力学和热力学性质。高级应用如反应路径模拟和蛋白质折叠研究,进一步扩展了 MD 模拟的应用范围。

kkchenjj的博客 1100

链表基础知识详解

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 ## 2.链表的组成 --- 链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时

Python老吕的博客 2133

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

链表基础知识

链表结构是内存内部的一种存储方式,可以把链表结构想象成是一串节点,由若干个节点穿成一串的数据结构。每个节点都有两个区域:数据域和指针域。指针域指向下一个节点的地址。下一个节点也是包含一个数据域和一个指针域。在链表结构中,之所以能成为链表结构,是因为有一个指针域。指针域存储的是下一个节点的引用(相关的引用) 指针域: c->内存中的一个地址,地址可以唯一标记一个节点的位置 某些特殊的写法,指针域可能存储的是数组下标。数组下标是特殊的地址。下标是相对地址的概念。 引用:js,Java,python 在相关

白水煮青菜的博客 7780

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

链表python基础知识

跟着datawhale刷力扣,以下基本来自于其文档,感谢 链表基本类型 链表(Linked List):一种线性表数据结构。它使用一组任意的存储单元(可以是连续的,也可以是不连续的),来存储一组具有相同类型的数据。即「链表」 是实现线性表的链式存储结构的基础。 单链表每个数据元素占用若干存储单元的组合称为一个「链节点」,还要存放一个指出这个数据元素在逻辑关系上的直接后继元素所在链节点的地址,该地址被称为「后继指针 next」。 双向链表(Doubly Linked List):链表的一种,也叫做双链表。它的

qq_44941689的博客 1万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

关于链表的基础知识

讲述了单链表的增删改查

2401_82376751的博客 927

【leetcode 力扣刷题】链表基础知识 基础操作

删除节点时,将被删除节点的前面节点和后面节点连接起来的同时,断开被删除节点和其前面一个、后面一个节点的连接,并且要释放掉被删除节点的空间:pre->next = cur->next;delete cur。在链表中的一个位置插入节点,需要先断开插入位置前后两个节点的链接,再和这两个节点建立新的链接:先cur->next = pre->next;构成的,数据域是一个节点的数据,指针域存储下一个节点的地址,下一个节点依靠上一个节点的指针域寻址。将尾节点看作是下一个节点是null的节点,处理和其他节点一样。

massive_jiang的博客 882
上一篇: 数据结构——顺序表基础知识
下一篇: 动态顺序表的基本操作(C语言版)
Code_zx
博客等级 码龄9年 83粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值