链表

对链表进行排序

本秂侑毒 提交于 2021-01-09 12:30:39
#include<stdio.h> #include<stdlib.h> #include<malloc.h> struct node { int data; struct node *pnext; }; struct node *creat_list();//创建链表函数 void traverse_list(struct node *phead);//遍历链表函数 bool is_empty(struct node *phead);//判断链表是否为空函数 int lenght_list(struct node *phead);//计算链表长度的函数 void sort_list(struct node *phead);//对链表进行排序 int insert_list(struct node *phead,int weizhi,int shu );//插入节点函数 int delete_list(struct node *phead ,int weihzi);//删除节点函数 int main() { struct node *phead; phead=creat_list(); traverse_list(phead); if(is_empty(phead)) printf("链表不为空!\n"); else printf("链表为空!\n"); int len

heap和stack的区别

爱⌒轻易说出口 提交于 2020-04-08 06:35:19
参考《程序员面试宝典》 1、栈区(stack) 由编译器自动分配和释放,存放函数的参数值,局部变量值等。其操作方式类似于数据中的栈。 2、堆区(heap) 一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。 3、全局区(静态区static) 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放。 4、文字常量区 常量字符串存放在此处,程序结束后由系统释放。 5、程序代码区 存放函数体的二进制代码。 堆和栈的理论知识如下: 1、申请方式: 栈:系统自动分配。 堆:程序员自己申请,并指明大小,c中使用函数malloc,c++中使用new。 2、申请后系统的响应 栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。 堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆节点,然后将该节点从空闲节点链表中删除,并将该节点的空间分配给程序。对于大多数系统,会在这块内存空间中的首地址处记录分配的代销。这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆节点大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。 3、申请大小的限制 栈

Java HashMap源码详解

夙愿已清 提交于 2020-04-08 01:30:17
Java数据结构-HashMap 目录 Java数据结构-HashMap 1. HashMap 1.1 HashMap介绍 1.1.1 HashMap介绍 1.1.2 HashMap继承图 1.2 HashMap 组成结构 1.2.1 Hashmap底层数据结构 2.HashMap源码解析 2.1 HashMap属性源码解析 2.1.1 HashMap中的静态常量 2.1.2 HashMap中的属性 2.1.2 HashMap中的存储结点 2.1.3 Hash表 2.2 方法源码分析 2.2.1 构造方法分析 2.2.2 Put(K key,V value) 待续... 1. HashMap 1.1 HashMap介绍 1.1.1 HashMap介绍 HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做 Entry ,有着key与value两个基本属性以及有其他的包含其他结点位置信息的属性 通过HashMap我们可以存储键值对,并且可以在较短的时间复杂度内, 1.1.2 HashMap继承图 HashMap通过继承 AbstractMap 实现了 Map 接口,且本身也实现了 Map 接口 在接口实现关系上来看为多余操作 但有一点要注意,在使用 反射获取实现接口 时,如果不是显示实现某接口而是通过继承来实现该接口,则不会获取该接口类型,这一点在使用

C++ STL,list vector区别

拟墨画扇 提交于 2020-04-08 00:56:40
顺序性容器: 向量 vector : 是一个线性顺序结构。相当于数组,但其大小可以不预先指定,并且自动扩展。它可以像数组一样被操作,由于它的特性我们完全可以将vector 看作动态数组。 在创建一个vector 后,它会自动在内存中分配一块连续的内存空间进行数据存储,初始的空间大小可以预先指定也可以由vector 默认指定,这个大小即capacity ()函数的返回值。当存储的数据超过分配的空间时vector 会重新分配一块内存块,但这样的分配是很耗时的,在重新分配空间时它会做这样的动作: 首先,vector 会申请一块更大的内存块; 然后,将原来的数据拷贝到新的内存块中; 其次,销毁掉原内存块中的对象(调用对象的析构函数); 最后,将原来的内存空间释放掉。 如果vector 保存的数据量很大时,这样的操作一定会导致糟糕的性能(这也是vector 被设计成比较容易拷贝的值类型的原因)。所以说vector 不是在什么情况下性能都好,只有在预先知道它大小的情况下vector 的性能才是最优的。 vector 的特点: (1) 指定一块如同数组一样的连续存储,但空间可以动态扩展。即它可以像数组一样操作,并且可以进行动态操作。通常体现在push_back() pop_back() 。 (2) 随机访问方便,它像数组一样被访问,即支持[ ] 操作符和vector.at() (3) 节省空间

C语言进阶之路(一)----C语言的内存四区模型

这一生的挚爱 提交于 2020-04-07 21:51:32
1.内存四区模型: 操作系统给C/C++编写的程序分配内存,通常将分配的内存划分为以下四个区域: 1.1栈区(stack):栈stack是一种先进后出的内存结构,所有的局部变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出,用完由操作系统自动释放 1.2堆区(heap):堆区需要程序员手动分配,手动释放,在C语言中可使用malloc进行分配。 1.3数据区: 静态区:全局变量以及程序中的静态变量。 常量区(static):字符串、常量。C编译器对于相同的字符串会自动进行优化分配为统一的地址。 1.4代码区: 存放程序的二进制代码,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不可以在运行期间修改的。 例子: //main.cpp int a = 0; //全局初始化区 char *p1; //全局未初始化区 main() { int b; //栈 char s[] = "abc"; //栈 ,编译时将"abc"存储到常量区,运行时将常量区的值拷贝靠栈区。 char *p2; //栈 char *p3 = "123456"; //123456\\0在常量区,p3在栈上。 static int c =0;//全局(静态)初始化区 p1 = (char *)malloc(10); p2 = (char *

LFU五种实现方式,从简单到复杂

徘徊边缘 提交于 2020-04-07 10:15:48
前言 最近刷力扣题,对于我这种 0 基础来说,真的是脑壳疼啊。这个月我估计都是中等和困难题,没有简单题了。 幸好,力扣上有各种大牛给写题解。看着他们行云流水的代码,真的是羡慕不已。让我印象最深刻的就是人称 “甜姨” 的知心姐姐,还有名叫威哥的大哥。几乎每天他们的题解我都是必看的。 甜姨的题解,虽然姿势很帅,但是对于我这种新手来说,感觉不是太友好,因为思路写的太少,不是很详细。所以,每次我看不明白的时候,都得反复看好几遍,才能想明白她代码中的思路。 上个周末的一道题是,让实现一个 LFU 缓存算法。经过我几个小时的研究(其实,应该有8个小时以上了,没得办法啊,菜就得多勤奋咯),终于把甜姨的思路整明白了。为了便于以后自己复习,就把整个思路记下来了,并配上图示和大量代码注释,我相信对于跟我一样的新手来说,是非常友好的。 经过甜姨同意,参考来源我也会贴出来: https://leetcode-cn.com/problems/lfu-cache/solution/java-13ms-shuang-100-shuang-xiang-lian-biao-duo-ji/ 虽然,力扣要求是用时间复杂度 O(1) 来解,但是其它方式我感觉也有必要了解,毕竟是一个由浅到深的过程,自己实现一遍总归是好的。因此,我就把五种求解方式,从简单到复杂,都讲一遍。 LFU实现 力扣原题描述如下: 请你为

链表排序--Sort List

…衆ロ難τιáo~ 提交于 2020-04-07 05:54:57
https://leetcode.com/problems/sort-list/ Sort List Sort a linked list in O ( n log n ) time using constant space complexity. 来自http://www.cnblogs.com/zuoyuan/p/3699508.html 南郭子綦 的解析 题目:链表的排序。要求:时间复杂度O(nlogn),空间复杂度O(1)。 解题思路:由于题目对时间复杂度和空间复杂度要求比较高,所以查看了各种解法,最好的解法就是归并排序,由于链表在归并操作时并不需要像数组的归并操作那样分配一个临时数组空间,所以这样就是常数空间复杂度了,当然这里不考虑递归所产生的系统调用的栈。      这里涉及到一个链表常用的操作,即快慢指针的技巧。设置slow和fast指针,开始它们都指向表头,fast每次走两步,slow每次走一步,fast到链表尾部时,slow正好到中间,这样就将链表截为两段。 1 # Definition for singly-linked list. 2 # class ListNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 7 class Solution: 8 # @param

concurrent包的数据结构

ぐ巨炮叔叔 提交于 2020-04-07 03:50:47
concurrent包的数据结构:阻塞的结构都是用lock加锁(lock会休眠锁),非阻塞是用CAS直接for循环加入。 结构简介 名称 功能 组成 原子量 AtomicBoolean Unsafe+==volatile int value== AtomicInteger Unsafe+==volatile int value== AtomicIntegerArray Unsafe+==final int[] array== AtomicLong Unsafe+==volatile long value== AtomicLongArray Unsafe+==final int[] array== 名称 功能 组成 阻塞队列 ==继承: BlockingQueue 接口== ArrayBlockingQueue 数组+lock LinkedBlockingQueue 链表+lock PriorityBlockingQueue**(优先级队列)** 自定义哪个队列先出 数组+lock DelayQueue (时间队列) 队列中每个元素都有个过期时间,并且队列是个优先级队列,当从队列获取元素时候,只有过期元素才会出队列 PriorityQueue(优先级队列)+lock SynchronousQueue 一个不存储元素的阻塞队列 阻塞队列(双端) ==继承: BlockingDeque

从尾到头打印链表

允我心安 提交于 2020-04-07 01:40:43
题目: 输入一个链表,按链表从尾到头的顺序返回一个ArrayList。 解答: /** * public class ListNode { * int val; * ListNode next = null; * <p> * ListNode(int val) { * this.val = val; * } * } */ import java.util.ArrayList; import java.util.Stack; public class Solution { public ArrayList<Integer> printListFromTailToHead(ListNode listNode) { ArrayList<Integer> arrayList = new ArrayList<Integer>(); Stack<Integer> stack = new Stack<Integer>(); int element = 0; // 入栈 while (listNode != null) {/*链表不为空:listNode != null*/ stack.push(listNode.val); listNode = listNode.next; } // 出栈 while (!stack.isEmpty()) {/*栈不为空:stack.isEmpty()*/

【LeetCode】21. 合并两个有序链表

删除回忆录丶 提交于 2020-04-07 00:00:40
题目 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。 示例1: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 限制:0 <= 链表长度 <= 1000 本题同 【剑指Offer】面试题25. 合并两个排序的链表 思路一:迭代 添加一个虚拟节点处理头结点。 代码 时间复杂度:O(m + n) 空间复杂度:O(1) class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if (!l1 || !l2) return l1 ? l1 : l2; ListNode *newHead = new ListNode(-1), *pre = newHead; while (l1 && l2) { if (l1->val <= l2->val) { pre->next = l1; l1 = l1->next; } else { pre->next = l2; l2 = l2->next; } pre = pre->next; } pre->next = l1 ? l1 : l2; return newHead->next; } }; 思路二:递归 代码 时间复杂度:O(m + n) 空间复杂度:O(1) class Solution {