文章目录

  • 单链表的相关操作 c语言实现

单链表的相关操作 c语言实现

其中有两个重要的算法需要注意

  • 判断链表是否有环
  • 翻转链表
#include <stdio.h>struct single_list {struct single_list *next;int val;
};struct single_list_head{struct single_list *head;
};bool is_empty(struct single_list_head *head)
{return head->head == NULL;
}//删除节点,传入的是节点的地址
struct single_list* del(struct single_list **prev)
{struct single_list *tmp;if (!prev)return NULL;tmp = *prev;//将节点指向的节点后移一位实现删除*prev = (*prev)->next;tmp->next = NULL;return tmp;
}//删除头结点
struct single_list* delete_head(struct single_list_head* head)
{return del(&head->head);
}//采用的是头插法进行列表的建立
void insert(struct single_list **prev, struct single_list *elem)
{if (!prev){return;}if (*prev){elem->next = *prev;}*prev = elem;
}//在头结点之前插入数据
void insert_head(struct single_list_head *head, struct single_list *elem)
{insert(&head->head, elem);
}//显示链表中的内容
void dump(struct single_list_head *head)
{struct single_list *tmp = head->head;int idx = 0;while(tmp){printf("[%02d]: %08d\n", idx++, tmp->val);tmp = tmp->next;}
}//查找节点值为target的节点位置
struct single_list** search(struct single_list_head *head, int target)
{struct single_list **prev, *tmp;for (prev = &head->head, tmp = *prev; \tmp && (tmp->val < target); \prev = &tmp->next, tmp = *prev);return prev;
}//获取链表中间的节点
struct single_list* middle(struct single_list_head* head)
{struct single_list *s1, *s2;struct single_list pseudo_head;pseudo_head.next = head->head;s1 = s2 = &pseudo_head;while (true){if (!s2 || !s2->next)return s1;s1 = s1->next;s2 = s2->next->next;}return NULL;
}//判断列表是否有环,快慢指针
bool is_cyclic(struct single_list_head* head)
{struct single_list *s1, *s2;s1 = s2 = head->head;while(s1 && s2){s1 = s1->next;//如果s2->next非空,则s2 = s2->next->next,否则s2 = s2->nexts2 = s2->next ? s2->next->next : s2->next;if (s1 == s2){return true;}}return false;
}//翻转链表
void reverse(struct single_list_head* head)
{struct single_list_head tmp = {NULL};struct single_list *elem;while(!is_empty(head)){elem = delete_head(head);insert_head(&tmp, elem);}head->head = tmp.head;
}int main()
{struct single_list_head head = {NULL};struct single_list lists[10];struct single_list **prev;int idx;for (idx = 0; idx < 10; idx++){lists[idx].val = idx;lists[idx].next = NULL;}insert_head(&head, &lists[6]);insert_head(&head, &lists[5]);insert_head(&head, &lists[4]);insert_head(&head, &lists[1]);insert_head(&head, &lists[0]);printf("== insert 0, 1, 4, 5, 6\n");dump(&head);//由于当前链表中没有2,所有最后找到的是4所在的位置prev = search(&head, 2);printf("find %d\n", (*prev)->val);insert(prev, &lists[2]);printf("=== insert 2\n");dump(&head);printf("middle elem is %d\n", middle(&head)->val);//找到值为2的节点prev = search(&head, 2);if ((*prev) && ((*prev)->val == 2))printf("The list contains 2\n");elseprintf("The list not contains 2\n");//删除节点为2printf("prev is %d\n", (*prev)->val);//prev 存放的是值为2的节点的地址del(prev);prev = search(&head, 2);printf("After remove 2\n");if ((*prev) && ((*prev)->val == 2))printf("The list contains 2\n");elseprintf("The list not contains 2\n");dump(&head);printf("After reverse \n");//翻转链表reverse(&head);dump(&head);printf("middle elem is %d\n", middle(&head)->val);lists[0].next = &lists[6];printf("list is %s cycic\n", is_cyclic(&head) ? "" : " not");return 0;
}

运行结果:

== insert 0, 1, 4, 5, 6
[00]: 00000000
[01]: 00000001
[02]: 00000004
[03]: 00000005
[04]: 00000006
find 4
=== insert 2
[00]: 00000000
[01]: 00000001
[02]: 00000002
[03]: 00000004
[04]: 00000005
[05]: 00000006
middle elem is 2
The list contains 2
prev is 2
After remove 2
The list not contains 2
[00]: 00000000
[01]: 00000001
[02]: 00000004
[03]: 00000005
[04]: 00000006
After reverse
[00]: 00000006
[01]: 00000005
[02]: 00000004
[03]: 00000001
[04]: 00000000
middle elem is 4
list is  cycic

数据结构与算法之美day 6: 如何实现LRU缓存淘汰算法?相关推荐

  1. 数据结构与算法 / LRU 缓存淘汰算法

    一.诞生原因 缓存是一种提供数据读取性能的技术,在硬件设计.软件开发中有广泛的应用,比如常见的 CPU 缓存,DB 缓存和浏览器缓存等.但是缓存的大小是有限的,需要一定的机制判断哪些数据需要淘汰,即: ...

  2. 看动画轻松理解「链表」实现「LRU缓存淘汰算法」

    作者 | 程序员小吴,哈工大学渣,目前正在学算法,开源项目 「 LeetCodeAnimation 」5500star,GitHub Trending 榜连续一月第一. 本文为 AI科技大本营投稿文章 ...

  3. 算法必知 --- LRU缓存淘汰算法

    作者:_code_x 链接:https://www.jianshu.com/p/b7fed77324b9 写在前 就是一种缓存淘汰策略. 计算机的缓存容量有限,如果缓存满了就要删除一些内容,给新内容腾 ...

  4. 06 | 链表(上):如何实现LRU缓存淘汰算法?

    缓存 作用 缓存是一种提高数据读取性能的技术,在硬件设计.软件开发中都有着非常广泛的应用,比如常见的 CPU 缓存.数据库缓存.浏览器缓存等等. 淘汰策略 常见的策略有三种:先进先出策略 FIFO(F ...

  5. 看动画轻松理解「链表」实现「 LRU 缓存淘汰算法」

    作者 | 吴至波 责编 | 胡巍巍 快速挑战Python全栈工程师: https://edu.csdn.net/topic/python115?utm_source=csdn_bw 前几节学习了「链表 ...

  6. 看动画理解「链表」实现LRU缓存淘汰算法

    前几节学习了「链表」.「时间与空间复杂度」的概念,本节将结合「循环链表」.「双向链表」与 「用空间换时间的设计思想」来设计一个很有意思的缓存淘汰策略:LRU缓存淘汰算法. 循环链表的概念 如上图所示: ...

  7. leetcode刷题:LRU缓存淘汰算法

    题目: 分析: 计算机的缓存容量有限,如果缓存满了就要删除一些内容,给新内容腾位置.但问题是,删除哪些内容呢?我们肯定希望删掉哪些没什么用的缓存,而把有用的数据继续留在缓存里,方便之后继续使用.那么, ...

  8. LRU缓存淘汰算法优化

    上文中提到了LRU 缓存淘汰算法,可以帮助我们更好更合理的去使用缓存.但是它也有一个缺点就是如果有一些不满足"如果数据最近被访问过,那么将来被访问的几率也更高"的规律时,会破坏缓存 ...

  9. 如何基于链表实现 LRU 缓存淘汰算法?

    什么是LRU LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是"如果数据最近被访问过,那么将来被访问的几率也更高" ...

最新文章

  1. 学精算的计算机知识,精算学专业学什么 附学习科目和课程
  2. Grails里DOMAIN类的一对一,一对多,多对多关系总结及集成测试
  3. python 代码-代码的重试机制(python简单实现)
  4. 利用Flume将MySQL表数据准实时抽取到HDFS
  5. 合并流程处理及逆向操作
  6. ADO 数据类型转换表[转]
  7. 数据湖三种方案的流行度调查
  8. oracle adg 改密码,Oracle ADG数据库切换
  9. java formatter()_Java Formatter locale()用法及代码示例
  10. junit测试一个方法,报test class not found in selected project
  11. JavaScript练习
  12. OpenSSL笔记-PKCS#1和PKCS#8的区别及分别调用的API
  13. 创建wincc项目提示无法连接到服务器,wincc 项目管理器 服务器不可用 无法连接到服务器...
  14. 如何修改sql服务器名,修改计算机名并更新sqlserver中存储的服务器名称
  15. 一款好用的设计师导航,让设计师拥有良好的设计体验
  16. VUE项目中安装和使用vant组件
  17. 零基础入门学习Python(31)--永久存储:腌制一缸美味的泡菜
  18. 匿名科创--ANO_OPENMV视觉开发板介绍
  19. FastDFS,Redis,Solr,ActiveMQ核心技术整合五
  20. java的byte和C#的byte的不同之处

热门文章

  1. 2022-2028年中国完全生物降解塑料产业发展动态及投资前景预测报告
  2. 安全保密领域人工智能的应用
  3. leetcode 30. Substring with Concatenation of All Words 与所有单词相关联的字串 滑动窗口法
  4. ServletContext讲解
  5. 【Spring】spring5新特性
  6. 2018半年总结:走过的路
  7. 微服务架构必备的几点知识
  8. 正则表达式(括号)、[中括号]、{大括号}的区别小结
  9. 通俗理解条件熵-数学
  10. 理解和实现分布式TensorFlow集群完整教程