链表的基础知识

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


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);
}

SAP BAPI调用避坑指南:处理MD61/MD62计划独立需求时,这些参数和返回值你必须检查 本文详细解析了SAP BAPI调用中处理MD61/MD62计划独立需求的关键参数和返回值检查要点,包括版本控制、日期类型和删除标记等核心参数设置,以及常见错误排查和高级调试技巧,帮助开发者高效管理需求计划数据。 阅读详情

相关推荐

高通ISP模块全解析:从Raw到JPEG的18个关键处理步骤(附避坑指南)

本文全面解析高通ISP模块从Raw到JPEG的18个关键处理步骤,涵盖原始数据预处理、色彩科学处理链、画质增强与降噪等核心环节。通过实战调优经验,揭示ISP架构中的技术原理与工程实践要点,帮助开发者避免常见问题,提升移动影像处理质量。

weixin_30399155的博客 359

链表基础知识总结

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

闲适_ 1万+

告别夜间噪点!用瑞芯微RV1126B的AI-ISP,手把手教你打造0.01Lux超低光摄像头

本文详细介绍了如何利用瑞芯微RV1126B芯片的AI-ISP技术,打造0.01Lux超低光摄像头,解决夜间噪点问题。通过AI算法与图像信号处理的深度融合,RV1126B的3TOPS边缘算力实现了像素级AI降噪和语义感知增强,显著提升低光环境下的图像质量。文章包含硬件选型、软件配置和实战调优指南,助力开发者在AIoT领域实现高性能视觉应用。

weixin_33725722的博客 565

线性结构-链表

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

m0_51274562的博客 1039

绿标短网址app.10086.cn/xxxxx移动短网址缩短接口网址api调用php方式解析

绿标短网址app.10086.cn/xxxxx 移动网缩短接口网址api调用php方式解析 app.10086.cn是移动网站的接口,可以制作移动网等第三方官方网站域名的任意生成接口,由于是认证企业,可以再抖音 微信 qq等第三方渠道正常打开不拦截提示,第三方网址,头条文章等,效果非常号,这里记录下api接口,纯技术php生成,具体规则可以去抖音的开放平台去申请对应接口 。这里用我php模拟抓包获取方式 GET http://www.app10086cn.cn/?i=app.10068.cnHTTP/1.1

qq_20300095的博客 5908

Coze HTTP请求节点实战:5分钟搞定天气API对接(含动态参数技巧)

本文通过一个天气预报API对接的实战案例,详细讲解了如何在Coze平台使用HTTP请求节点实现外部数据交互。文章重点演示了动态参数传递、JSON响应解析与错误处理等核心技巧,帮助开发者在5分钟内快速构建稳定可靠的智能体外部服务调用能力。

weixin_29233333的博客 676

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

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

酒无忧的博客 1839

802.1AS时间同步机制深度解析:从Sync报文到多域冗余设计

本文深度解析了802.1AS时间同步机制,从Sync与Follow_Up报文的核心交互原理入手,详细阐述了其如何通过精确的时钟频率比测量、链路延迟计算和驻留时间补偿来实现微秒乃至纳秒级同步。文章进一步探讨了802.1AS-2020版本引入的多时钟域冗余设计,为构建高可靠的车载TSN网络提供了关键见解和实战配置指南。

pytorch8learner的博客 460

链表知识点总结

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

Lookdrama的博客 1407

4. PCIe 接口时序

在上一篇中,大致介绍IPcore接口。总的来说接口如下图数据的接收和发送通过transmitTLPinterface和ReceiveTLPinterface。收发数据的时序也只是描述这几个接口的关系。从手册上截取PCIex1的接口时序。

jjinl的专栏 6122

手把手教你学Simulink--基于Simulink的高增益DC-DC变换器仿真建模

特点高电压增益:可以在不使用变压器的情况下实现较大的电压升压比。适用于低电压源:如太阳能电池板、燃料电池等提供的低压直流电源。效率问题:设计时需特别注意提高效率,减少能量损失。挑战电路复杂性:通常涉及多个电感和电容,以及复杂的开关模式。元件选择:合适的元件参数对于达到理想性能至关重要。控制策略:确保高效稳定运行的同时,适应负载变化。首先明确要模拟的任务内容。实现特定的电压增益比(例如从24V升至380V)。根据预期的输入输出电压确定合适的电路拓扑和元件值。

MHD0815的博客 173

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

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

lhyhaiyan的博客 6123

在最新版eclipse中配置使用AI AIcoder _AIcoder配置GPUSTACK使用_配置OLLAMA本地AI模型利用_集合---AI场景应用工作笔记

本文介绍了三款实用的编程辅助工具:一款便捷的反编译插件,可直接在插件市场安装使用;GitHub Copilot提供每月2000次代码补全和50条聊天记录的免费额度,支持智能代码提示功能;aicoder支持配置本地模型运行。这些工具都能有效提升开发效率,其中GitHub Copilot的智能补全功能尤为突出。

添柴程序猿的专栏 1243

链表基础知识详解

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

Python老吕的博客 2133

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

链表基础知识

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

白水煮青菜的博客 7780

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

链表python基础知识

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

qq_44941689的博客 1万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

关于链表的基础知识

讲述了单链表的增删改查

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、付费专栏及课程。

余额充值