当前位置: 首页 > news >正文

C语言--day20

补充:单向链表

查找:根据数据查找,返回找到的节点
Node_t *find_link_node(Link_t *plink, Datatype_t data) { if (is_empty_link(plink)) { return NULL; } Node_t *ptmp = plink->phead; while (ptmp != NULL) { if (ptmp->data == data) { return ptmp; } ptmp = ptmp->pnext; } return NULL; }
修改:修改旧值为新值
int change_link(Link_t *plink, Datatype_t new, Datatype_t old) { Node_t *ptmp = NULL; ptmp = find_link_node(plink, old); if (ptmp != NULL) { ptmp->data = new; return 0; } return -1; }
查找链表中间结点,返回中间结点的地址
Node_t *find_mid_node(Link_t *plink) { if (is_empty_link(plink)) { return NULL; } Node_t *pfast = plink->phead; Node_t *pslow = pfast; while (pfast != NULL) { pfast = pfast->pnext; if (NULL == pfast) { break; } pfast = pfast->pnext; pslow = pslow->pnext; } return pslow; }
输出:
Node_t *ptmp = NULL; ptmp = find_link_node(plink, 4); //查找 if (ptmp != NULL) { printf("find %d\n", ptmp->data); } change_link(plink, 100, 3); //修改 show_link(plink); ptmp = find_mid_node(plink); //查找中间值 if (ptmp != NULL) { printf("Mid node : %d\n", ptmp->data); }
查找倒数第k个节点

Node_t *find_last_k_node(Link_t *plink, int k) { if (is_empty_link(plink)) { return NULL; } Node_t *pfast = plink->phead; Node_t *pslow = pfast; for (int i = 0; i < k; i++) { if (NULL == pfast) { return NULL; } pfast = pfast->pnext; } while (pfast != NULL) { pfast = pfast->pnext; pslow = pslow->pnext; } return pslow; }
ptmp = find_last_k_node(plink, k); if (ptmp != NULL) { printf("Last k %d\n", ptmp->data); }
单向链表的倒置
void reverse_link(Link_t *plink) { if (is_empty_link(plink)) { return ; } Node_t *pinset = NULL; Node_t *ptmp = plink->phead; plink->phead = NULL; while (ptmp != NULL) { pinset = ptmp; ptmp = ptmp->pnext; pinset->pnext = plink->phead; plink->phead = pinset; } return; }
单向链表的插入排序
void sort_link_insert(Link_t *plink) { if (is_empty_link(plink) || 1 == plink->clen) { return; } Node_t *pinsert = NULL; Node_t *ptmp = plink->phead->pnext; plink->phead->pnext = NULL; while (ptmp != NULL) { pinsert = ptmp; ptmp = ptmp->pnext; if (pinsert->data <= plink->phead->data) { pinsert->pnext = plink->phead; plink->phead = pinsert; } else { Node_t *p = plink->phead; while (p->pnext != NULL && p->pnext->data < pinsert->data) { p = p->pnext; } pinsert->pnext = p->pnext; p->pnext = pinsert; } } }
循环链表(单向链表)

int is_loop_link(Link_t *plink) { Node_t *pfast = plink->phead; Node_t *pslow = pfast; while (pfast != NULL) { pfast = pfast->pnext; if (NULL == pfast) { return 0; } pfast = pfast->pnext; pslow = pslow->pnext; if (pslow == pfast) { return 1; } } return 0; }
ptmp = plink->phead; while (ptmp->pnext != NULL) { ptmp = ptmp->pnext; } ptmp->pnext = plink->phead->pnext->pnext; if (is_loop_link(plink)) { printf("Is a loop link\n"); } else { printf("Is not a loop link\n"); }
  • 单向链表:无法通过当前结点访问前驱结点
  • 双向链表:增加指向前驱结点的指针域,即可从前向后遍历,也可从后向前遍历

双向链表

双向链表的创建:
DLink_t *create_doulink() { DLink_t *pdlink = malloc(sizeof(DLink_t)); if (NULL ==pdlink) { printf("malloc error\n"); return NULL; } pdlink->phead = NULL; pdlink->clen = 0; return pdlink; } DNode_t *create_node(DataType_t data) { DNode_t *pnode = malloc(sizeof(DNode_t)); if (NULL == pnode) { printf("malloc error\n"); return NULL; } pnode->data = data; pnode->pnext = NULL; pnode->ppre = NULL; return pnode; } int is_empty_dlink(DLink_t *pdlink) { if (NULL == pdlink->phead) { return 1; } return 0; }
双向链表的遍历:
​ void show_pdlink(DLink_t *pdlink,int dir) { if (is_empty_dlink(pdlink)) { return; } DNode_t *ptmp = pdlink->phead; if(dir) { while (ptmp) { printf("%d %s %d\n",ptmp->data.id,ptmp->data.name,ptmp->data.score); ptmp= ptmp->pnext; } } else { while (ptmp->pnext) { ptmp = ptmp->pnext; } while (ptmp) { printf("%d %s %d\n",ptmp->data.id,ptmp->data.name,ptmp->data.score); ptmp = ptmp->ppre; } } printf("\n"); } ​
int main(int argc, const char *argv[]) { DLink_t *pdlink = NULL; pdlink = create_doulink(); if (NULL == pdlink) { return -1; } DataType_t s[] = {{1, "张三", 60}, {2, "王麻子", 100},{3, "萧火火", 100}, {4, "韩老魔", 95}}; insert_doulink_head(pdlink, s[0]); insert_doulink_head(pdlink, s[1]); insert_doulink_head(pdlink, s[2]); insert_doulink_head(pdlink, s[3]); show_pdlink(pdlink,1); }
双向链表的头插:

int insert_doulink_head(DLink_t *pdlink, DataType_t data) { DNode_t *pnode = create_node(data); if (NULL == pnode) { return -1; } if (is_empty_dlink(pdlink)) { pdlink->phead = pnode; } else { pnode->pnext = pdlink->phead; pdlink->phead->ppre = pnode; pdlink->phead = pnode; } pdlink->clen++; return 0; }
双向链表的尾插:
int insert_doulink_tail(DLink_t *pdlink, DataType_t data) { DNode_t *pnode = create_node(data); if (NULL == pnode) { return -1; } DNode_t *ptmp = pdlink->phead; if (is_empty_dlink(pdlink)) { pdlink->phead = pnode; } else { while (ptmp->pnext != NULL) { ptmp = ptmp->pnext; } ptmp->pnext = pnode; pnode->ppre = ptmp; } pdlink->clen++; return 0; }
双向链表的头删:
int delete_doulink_head(DLink_t *pdlink) { if (is_empty_dlink(pdlink)) { return -1; } DNode_t *ptmp = pdlink->phead; pdlink->phead = ptmp->pnext; if (ptmp->pnext != NULL) { ptmp->pnext->ppre = NULL; } free(ptmp); pdlink->clen--; return 0; }
双向链表的尾删:
int delete_doulink_tail(DLink_t *pdlink) { if (is_empty_dlink(pdlink)) { return -1; } DNode_t *ptmp = pdlink->phead; while (ptmp->pnext != NULL) { ptmp = ptmp->pnext; } if (ptmp->ppre != NULL) { ptmp->ppre->pnext = NULL; } else { pdlink->phead = NULL; } free(ptmp); pdlink->clen--; return 0; }
双向链表-->>根据name查找到修改成绩
int change_doulink(DLink_t *pdlink, char *name, int score) { DNode_t *ptmp = NULL; ptmp = find_doulink(pdlink, name); if (ptmp != NULL) { ptmp->data.score = score; return 0; } return -1; }
段错误调式

了解内核链表:
  • 本质:双向循环链表、有头链表
  • 不将数据存储在链表结点中,而是将结点嵌入到要存储的数据中
  • 好处:该链表可以用来存储任意类型的数据,增强代码的复用性
  • offsetof : 获取链表结点到结构体起始位置的偏移量
  • container_of : 通过偏移量获取结构体首地址

栈(先进后出)

  • 栈:数据结构中的一种线性存储结构
  • 只允许从一端进行数据插入和删除的线性存储结构
  • 特点:先进后出(FILO)

  • 顺序栈:空间连续
  • 链式栈:非连续空间

顺序栈:

  • 满增栈、空增栈、满减栈、空减栈
  • 满栈/空栈:栈顶所在位置是否存有元素
  • 增栈/减栈:根据栈的生长方向决定

链式栈:

stack.h

#ifndef __STACK_H__ #define __STACK_H__ typedef int DataType_t; typedef struct node { DataType_t data; struct node *pnext; }SNode_t; typedef struct stack { SNode_t *ptop; int clen; }Stack_t; extern Stack_t *create_link_stack(); extern int push_stack(Stack_t *pstack, DataType_t data); extern void show_stack(Stack_t *pstack); extern int pop_stack(Stack_t *pstack, DataType_t *pdata); extern int get_stack_top(Stack_t *pstack, DataType_t *pdata); extern void destroy_stack(Stack_t *pstack); #endif
创建链式栈
#include "stack.h" #include <stdio.h> #include <stdlib.h> Stack_t *create_link_stack() { Stack_t *pstack = malloc(sizeof(Stack_t)); if (NULL == pstack) { printf("malloc error\n"); return NULL; } pstack->ptop = NULL; pstack->clen = 0; return pstack; } SNode_t *create_node(DataType_t data) { SNode_t *pnode = malloc(sizeof(SNode_t)); if (NULL == pnode) { printf("malloc error\n"); return NULL; } pnode->data = data; pnode->pnext = NULL; return pnode; }
链式栈入队(尾插)
int push_stack(Stack_t *pstack, DataType_t data) { SNode_t *pnode = create_node(data); if (NULL == pnode) { return -1; } pnode->pnext = pstack->ptop; pstack->ptop = pnode; pstack->clen++; return 0; }
链式栈出栈(头删)
int pop_stack(Stack_t *pstack, DataType_t *pdata) { if (is_empty_stack(pstack)) { return -1; } SNode_t *ptmp = pstack->ptop; pstack->ptop = ptmp->pnext; if (pdata != NULL) { *pdata = ptmp->data; } free(ptmp); pstack->clen--; return 0; }
链式栈获取队头元素
int get_stack_top(Stack_t *pstack, DataType_t *pdata) { if (is_empty_stack(pstack)) { return -1; } if (pdata != NULL) { *pdata = pstack->ptop->data; } return 0; }
链式栈销毁队列
void destroy_stack(Stack_t *pstack) { while (!is_empty_stack(pstack)) { pop_stack(pstack, NULL); } free(pstack); }
main.c(输出)
#include <stdio.h> #include "stack.h" int main(int argc, const char *argv[]) { Stack_t *pstack = NULL; DataType_t data; pstack = create_link_stack(); if (NULL == pstack) { return -1; } push_stack(pstack, 1); push_stack(pstack, 2); push_stack(pstack, 3); push_stack(pstack, 4); push_stack(pstack, 5); show_stack(pstack); int ret = pop_stack(pstack, &data); if (0 == ret) { printf("data = %d\n", data); } ret = get_stack_top(pstack, &data); if (0 == ret) { printf("top %d\n", data); } destroy_stack(pstack); return 0; }
http://www.jsqmd.com/news/899821/

相关文章:

  • 观察大模型API调用成本,Taotoken用量看板如何助力企业预算管理
  • 深度指南:2026现阶段河北地区专业阳光房实力厂商选择全解析 - 2026年企业资讯
  • 维普4月升级降AI失效?2026年5月仍有效的4款降AI软件实测
  • 对比自行维护多个API与使用Taotoken聚合在运维上的差异
  • 靠谱的17-4Ph不锈钢厂商推荐:高硬度耐磨不锈钢厂商联系方式 - 品牌2025
  • 实测HS0038红外接收头:3.3V和5V都能用,STM32F103直接驱动避坑指南
  • AI预约聊天机器人实战:从自然语言理解到GDPR合规部署
  • SAP FI 深度解析:OBCY配置下的会计凭证行项目合并实战与风险规避
  • 小白/程序员必备:收藏!轻松学会使用大模型进行数据验证
  • ChatGPT企业客户画像生成实录(脱敏版):金融/教育/医疗三大行业差异化建模路径对比
  • 物流系统如何打通信息孤岛?哲盟软件系统:一键打通内外部数据壁垒
  • 仿生六足机器人分层网络控制:从CPG原理到工程实现
  • 通过Hermes Agent自定义提供商接入Taotoken实现多工具链集成
  • 2026年Q2中央供料系统实力厂家选哪家?这份深度解析给你答案 - 2026年企业资讯
  • 17-共享发布与用户协作:平台如何让资产跨人流转
  • Ubuntu新手必看:除了Ctrl+C/V,Terminator里这些隐藏快捷键能让你效率翻倍
  • 压力变送器哪个牌子质量好?广东犸力数字补偿技术强,国产靠谱且性价比高 - 品牌速递
  • 如何将照片从iPad传输到计算机?
  • 27考研408计算机历年真题PDF
  • 【独家首发】中国首份《生成式AI合同审查白皮书》(工信部信通院联合审定),覆盖12类SaaS场景,仅限本周开放下载
  • 浏览器里的飞行实验室:零门槛玩转无人机日志分析
  • 大模型是“大脑“ Agent是“四肢“:AI智能体如何让AI从“空想家“变“实干家“?
  • 【立体匹配】从理论到实践:深度立体匹配算法演进与核心数据集解析
  • 2026年移动厕所厂家推荐榜单:工地/景区/展会/市政临时卫生间的品质之选 - 品牌企业推荐师(官方)
  • 抖音下载器:零门槛批量获取抖音内容的终极方案
  • REIS:基于存储内处理的高性能RAG检索系统优化
  • 生成式引擎优化(GEO)实战指南:面向ChatGPT、Perplexity与Gemini的内容策略
  • 大模型核心加速器:KV Cache 如何将 O(n²) 计算复杂度降至 O(n)?
  • 智能车电机调速实战:用IR2184搭建H桥驱动电路,附自举电容与栅极电阻详解
  • 2026年5月更新雄县有名的切割短管实力厂商推荐几家:谁能定义下一代行业标准? - 2026年企业资讯