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;

}

相关推荐
xieliyu.9 小时前
Java算法精讲:双指针(三)
java·开发语言·算法
CryptoPP10 小时前
快速对接东京证券交易所API数据:实战指南与代码示例
开发语言·人工智能·windows·python·信息可视化·区块链
ZC跨境爬虫10 小时前
跟着 MDN 学JavaScript day_7:数学运算与逻辑判断实战测试
开发语言·前端·javascript·学习·ecmascript
AI thought10 小时前
【转】C语言中 -> 是什么意思?
c语言·位移运算符·右移赋值·无符号整数·算术右移
阳区欠11 小时前
【LangChain】LLM基础介绍
开发语言·python·langchain
Jinkxs11 小时前
Java 跨域14-Java 与区块链(Hyperledger)集成
java·开发语言·区块链
晨曦中的暮雨12 小时前
Golang速通(Javaer版)
java·开发语言·后端·golang
小小编程路13 小时前
Python 还有容器类型互转、进制转换、字符编码转换
开发语言·windows·python
qeen8713 小时前
【C++】类与对象之类的默认成员函数(二)
android·c语言·开发语言·c++·笔记·学习
CRMEB系统商城13 小时前
CRMEB多商户系统(Java)v2.3公测版发布
java·开发语言·人工智能·小程序·开源·php