标签:测试方法 空闲 等等 结构 多少 trie树 霍夫曼树 哈夫曼树 矩阵
https://blog.csdn.net/yeyazhishang/article/details/82353846
因为哈希表是基于数组衍生的数据结构,在添加删除元素方面是比较慢的,所以很多时候需要用到一种数组链表来做,也就是拉链法。拉链法是数组结合链表的一种结构,较早前的hashMap底层的存储就是采用这种结构,直到jdk1.8之后才换成了数组加红黑树的结构。
图是一种比较复杂的数据结构,在存储数据上有着比较复杂和高效的算法,分别有邻接矩阵 、邻接表、十字链表、邻接多重表、边集数组等存储结构
栈:特点就是一个先进后出的结构。
队列:特点就是一个先进先出的结构。
栈的应用:非常广泛,在CPU内部就有提供栈这个机制。主要用途:函数调用和返回,数字转字符,表达式求值,走迷宫等等。在CPU内部栈主要是用来进行子程序调用和返回,中断时数据保存和返回。在编程语言中:主要用来进行函数的调用和返回。可以说在计算机中,只要数据的保存满足先进后出的原理,都优先考虑使用栈,所以栈是计算机中不可缺的机制。
队列的应用:队列主要用在和时间有关的地方,特别是操作系统中,队列是实现多任务的重要机制。windows中的消息机制就是通过队列来实现的。进程调度也是使用队列来实现,所以队列也是一个重要的机制。只要满足数据的先进先出原理就可以使用队列。
不同:
相同:两种结构均可实现数据的顺序存储,构造出来的模型呈线性结构。
区别一:物理地址存储的连续性
数组的元素在内存中是连续存放的。
链表的元素在内存中不一定是连续存放的,通常是不连续的。
区别二:访问速度
数组的访问速度很快,因为数组可以根据数组可以根据下标进行快速定位。
链表的访问速度较慢,因为链表访问元素需要移动指针。
区别三:添加、删减元素速度
数组的元素增删速度较慢,因为需要移动大量的元素。
链表的元素增删速度较快,因为只需要修改指针即可。
前缀树也叫字典树,常用语字符串的查找。
字典树==前缀树==Trie树:
查询某个单词(前缀)在所有单词中出现次数的一种数据结构
查询和插入时间复杂度都是O(n),是一种以空间换时间的方法。
详细介绍参考于: https://www.cnblogs.com/vincent1997/p/11237389.html (需要详细看)
https://blog.csdn.net/aiphis/article/details/48247469
应用:
前缀树有着广泛的应用,例如自动补全,拼写检查、搜索单词、搜索前缀等等
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。
通俗点讲,线程池就是一个容器,集中管理线程。线程使用完毕不会销毁,而是会先存储在线程池内。
1、判断线程池里的核心线程是否都在执行任务,如果不是(核心线程空闲或者还有核心线程没有被创建)则创建一个新的工作线程来执行任务。如果核心线程都在执行任务,则进入下个流程。
2、线程池判断工作队列是否已满,如果工作队列没有满,则将新提交的任务存储在这个工作队列里。如果工作队列满了,则进入下个流程。
3、判断线程池里的线程是否都处于工作状态,如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务。
https://blog.csdn.net/jiao1902676909/article/details/88980110
1、线程是稀缺资源,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以重复使用。
2、可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗过多内存导致服务器崩溃。
创建的线程池具体配置为:核心线程数量为5个;全部线程数量为10个;工作队列的长度为5
刚开始都是在创建新的线程,达到核心线程数量5个后,新的任务进来后不再创建新的线程,而是将任务加入工作队列,任务队列到达上限5个后,新的任务又会创建新的普通线程,直到达到线程池最大的线程数量10个,后面的任务则根据配置的饱和策略来处理。我们这里没有具体配置,使用的是默认的配置AbortPolicy:直接抛出异常。
一个应用场景
linux高并发的实现,线程池的实现思想,怎样处理高并发就比如说,用迅雷看电影。一边下载,一边播放。这个时候下载进程和播放进程,他们两个就有同步的机制,例如:只能播放视频文件中已经下载完成的部分,没有下载的不能播放。
https://blog.csdn.net/chenkaifang/article/details/81428799
并发是轮流处理多个任务,并行是同时处理多个任务
https://www.jianshu.com/p/cbf9588b2afb
①一个函数在他的函数体内调用他自身称为递归调用,执行递归函数将反复调用其自身,每执行一次进入新的一层。
②为防止递归函数无休止的进行,必须在函数内有终止条件。
③对于一个函数只要知道他的递归定义式和边界条件,就可以编递归函数。
层数不能太多,在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。
递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
充分必要条件是:问题具有某种可借用的类同自身的子问题描述的性质;某一有限步的子问题(也称本原问题)有直接的解存在。
递归算法就是通过解决同一问题的一个或多个更小的实例来最终解决一个大问题的算法。为了在C语言中实现递归算法,常常使用递归函数,也就是说能调用自身的函数。递归程序的基本特征:它调用自身(参数的值更小),具有终止条件,可以直接计算其结果。
在使用递归程序时,我们需要考虑编程环境必须能够保持一个其大小与递归深度成正比例的下推栈。对于大型问题,这个栈需要的空间可能妨碍我们使用递归的方法。
一个递归模型为分治法,最本质的特征就是:把一个问题分解成独立的子问题。如果子问题并不独立,问题就会复杂的多,主要原因是即使是这种最简单算法的直接递归实现,也可能需要难以想象的时间,使用动态规划技术就可以避免这个缺陷。
可以按照从最小开始的顺序计算所有函数值来求任何类似函数的值,在每一步使用先前已经计算出的值来计算当前值,我们称这项技术为自底向上的动态规划。只要有存储已经计算出的值的空间,就能把这项技术应用到任何递归计算中,就能把算法从指数级运行时间向线性运行时间改进。
性质:动态规划降低了递归函数的运行时间,也就是减少了计算所有小于或等于给定参数的递归调用所要求的时间,其中处理一次递归调用的时间为常量。
具体详见于:https://blog.csdn.net/DeepIT/article/details/6530282
在自顶向下的动态规划中,我们存储已知的值;在自底向上的动态规划中,我们预先计算这些值。我们常常选择自顶向下的动态规划而不选自底向上动态规划,其原因如下:
1 自顶向下的动态规划是一个自然的求解问题的机械转化。
2 计算子问题的顺序能自己处理。
3 我们可能不需要计算所有子问题的解。
我们不能忽视至关重要的一点是,当我们需要的可能的函数值的数目太大以至于不能存储(自顶向下)或预先计算(自底向上)所有值时,动态规划就会变得低效。自顶向下动态规划确实是开发高效的递归算法实现的基本技术,这类算法应纳入任何从事算法设计与实现所需的工具箱。
https://www.cnblogs.com/threetop/p/9075349.html
https://blog.csdn.net/qq_35556064/article/details/82503076
怎么判断一个元素是不是数组?
霍夫曼树:带权路径最短的二叉树称为哈夫曼树或最优二叉树
标签:测试方法 空闲 等等 结构 多少 trie树 霍夫曼树 哈夫曼树 矩阵
原文地址:https://www.cnblogs.com/GuoXinxin/p/11691262.html