C语言中 栈、队列、双向链表

一、双向链表

逻辑: 相较于单向链表,双向链表需要多存储一个上一节点的地址。

1. 节点的定义

typedef struct Node

{

int nVal;

struct Node* pNext;

struct Node* pLast;

}List;

2. 链表的添加

与单向链表相似,分成两种情况:链表中没有节点和链表中有节点

链表中没有节点,则新节点既链表中有节点是头结点也是尾节点。

链表中有节点,则新节点为尾节点,同时向前指针指向旧的尾节点

添加函数的定义:

void AddNode(List** ppHead, List** ppEnd, int nVal)

{

List* pTemp=malloc(sizeof(List));

pTemp->nVal =nVal;

pTemp->pLast = NULL;

pTemp->pNext = NULL;

if (*ppHead == NULL)

{

*ppHead = pTemp;

}

else

{

(*ppEnd)->pNext = pTemp;

pTemp->pLast = *ppEnd;

}

*ppEnd = pTemp;

}

3. 主函数中的使用:

int main()

{

List* pHead = NULL;

List* pEnd = NULL;

AddNode(&pHead, &pEnd, 1);

AddNode(&pHead, &pEnd, 2);

AddNode(&pHead, &pEnd, 3);

AddNode(&pHead, &pEnd, 4);

return 0;

}

二、队列

逻辑:先进先出,不允许插入

1.节点的定义

typedef struct Node

{

int nVal;

struct Node* pNext;

}Queue;

2.入队函数

void Push(Queue** ppHead, Queue** ppEnd, int nVal)

{

Queue* pTemp = malloc(sizeof(Queue));

pTemp->nVal = nVal;

pTemp->pNext = NULL;

if (NULL == *ppHead)

{

*ppHead = pTemp;

}

else

{

(*ppEnd)->pNext = pTemp;

}

*ppEnd = pTemp;

}

3.出队函数

int Pop(Queue** ppHead, Queue** ppEnd)

{

if (*ppHead != NULL)

{

Queue* pDel = *ppHead;

*ppHead = (*ppHead)->pNext;

int n = pDel->nVal;

free(pDel);

pDel = NULL;

if (NULL == *ppHead)

{

*ppEnd = NULL;

}

return n;

}

return -1;

}

4. 主函数中的使用:

int main()

{

Queue* pHead = NULL;

Queue* pEnd = NULL;

Push(&pHead, &pEnd, 1);

Push(&pHead, &pEnd, 2);

Push(&pHead, &pEnd, 3);

printf("%d\n", Pop(&pHead, &pEnd));

printf("%d\n", Pop(&pHead, &pEnd));

printf("%d\n", Pop(&pHead, &pEnd));

return 0;

}

三、栈

逻辑:后进先出

1.节点的定义

typedef struct Node

{

int nVal;

struct Node* pNext;

}Stack;

2.入栈函数

void Push(Stack** ppTop, int nVal)

{

Stack* pTemp= malloc(sizeof(Stack));

pTemp->nVal = nVal;

pTemp->pNext = *ppTop;

*ppTop = pTemp;

}

3.出栈函数

int Pop(Stack** ppTop)

{

if (*ppTop != NULL)

{

Stack* pDel = *ppTop;

*ppTop = (*ppTop)->pNext;

int n = pDel->nVal;

free(pDel);

pDel = NULL;

return n;

}

return -1;

}

4. 主函数中的使用:

int main()

{

Stack* pTop = NULL;

Push(&pTop, 1);

Push(&pTop, 2);

Push(&pTop, 3);

printf("%d\n", Pop(&pTop));

printf("%d\n", Pop(&pTop));

printf("%d\n", Pop(&pTop));

return 0;

}

相关推荐
格林威2 分钟前
工业相机Chunk功能全解析:图像嵌入时间戳、编码器元数据(附堡盟C#代码)
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
小大宇28 分钟前
Python 集成 Conda
开发语言·python·conda
天空'之城30 分钟前
C 语言工业级通用组件手写 08:精准软件消抖
c语言·嵌入式开发·工业级组件·软件消抖·按键防抖
还是奇怪44 分钟前
Simon Willison 用 DSPy 优化 Datasette Agent 提示词:提示工程正在变成可测试的软件工程
java·开发语言·软件工程
小大宇2 小时前
python flask框架 SSE流式返回、跨域、报错
开发语言·python·flask
Legendary_0082 小时前
LDR6500 设计指南:Type-C 音频快充二合一配件 PD 取电与插拔时序控制方案
c语言·开发语言·音视频
柒星栈2 小时前
PHP 源码怎么加密防破解?三套方案实战指南
开发语言·php·android studio
勉灬之2 小时前
Next.js + Prisma 跨平台部署踩坑记
开发语言·javascript·ecmascript
这是个栗子3 小时前
前端开发中的常用工具函数(九)
开发语言·javascript·ecmascript·at
蓝创工坊Blue Foundry3 小时前
图片文字提取到 Excel:批量任务如何先定义要交付的字段
运维·服务器·开发语言·数据库·自动化·ocr·excel