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;

}

相关推荐
揽星河..40 分钟前
【C语言】分支和循环
c语言·c++·算法
小熊恋旧41 分钟前
Python 面向对象编程:方法、属性、继承与多态详解
开发语言·python
云边云科技_云网融合42 分钟前
面向汽车零部件制造业场景的解决方案 | 70 秒:一台车下线的时间里,藏着五张网
开发语言·汽车·php
Evand J43 分钟前
【PMSM滤波例程2】PMSM未知负载转矩观测EKF。MATLAB例程(负载增广EKF与实际仿真结果)。附下载链接
开发语言·matlab·电机
will_net1 小时前
apollo 站点部署&C#接入
开发语言·c#·apollo
晗夜未央2 小时前
任务队列反复失败,先分清重试、阻塞和结果待核对
开发语言·javascript
熊猫钓鱼>_>2 小时前
四种书签,一条时间线:一个读书 App 的记忆颗粒与它的边界案例【鸿蒙心迹】
开发语言·华为·ai编程·harmonyos·鸿蒙·openharmony·鸿蒙pc
努力努力再努力wz2 小时前
【Lua 入门系列】Lua 函数深入理解:函数对象、多返回值、可变参数、闭包、递归与尾调用优化
开发语言·lua
揽星河..3 小时前
【C语言】猜数字游戏
c语言·算法·游戏
飞浪纪元[FWC–FE]3 小时前
从零到一键绿:Qt 5.14.2 + VS2019 开发环境搭建、Kit 套件配置与构建错误修复完全手册
开发语言·qt