Heapsort 和 priority queue

怎甘沉沦 提交于 2020-04-18 04:49:28
一、二叉堆含义及属性: 堆(heap)亦被称为:优先队列(priority queue),是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵完全二叉树的数组对象。在队列中,调度程序反复提取队列中第一个作业并运行,因而实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权。堆即为解决此类问题设计的一种数据结构。同垃圾收集存储的堆含义不同。 表示堆的数组A有两个属性: A.length : 代表A数组的元素个数; A.heapsize : 代表A数组中 属于堆元素个数。有时候(排序时),数组A的部分元素不属于堆。刚开始建堆的是偶,A.heapsize = A.length,排序时,每次从堆顶取出最大值,A.heapsize递减,直至排序完成. 下图是一个建好后的二叉堆: 从图中可知,已知某节点的索引值i,可以轻松获取其对应父节点,左,右子节点的索引值。有: Parent(i) return i/2; 或者 return i >> 1; Left(i) return i*2; 或者 return i << 1; Right(i) return i*2+1; 或者 return (i << 1) + 1; 二叉堆分两种: 最大堆,最小堆,均遵循堆属性。最大堆,每个节点i满足: A[Parent(i)] ≥ A[i]

Timer源码之TaskQueue

依然范特西╮ 提交于 2020-01-07 04:49:30
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> TaskQueue类是在Timer文件中的TaskQueue,它是一个又堆实现的优先队列。TaskQueue按任务剩下一次执行时间排序的优先级队列,使用的数据结构是小顶堆(保证堆顶的元素最小) 堆的性质并不保证有序,只是保证能在O(1)找到最小值(小顶堆)或者最大值(大顶堆) 堆本质上是一个完全二叉树,保证了根节点总是比叶子节点大或者小。因为这个优先级队列主要是由来存放TimerTask的,所以它使用的是一个TimerTask的数组来实现的。 import java.util.Arrays; import java.util.TimerTask; class TaskQueue { /** * 使用数组存为,数据是TimerTask类型 */ private TimerTask[] queue = new TimerTask[128]; /** * 任务队列的大小,queue[0]没有使用,queue[1]-queue[size]是排好序的 */ private int size = 0; int size() { return size; } /** * */ TimerTask getMin() { return queue[1]; } TimerTask get(int i) { return queue

Head First C学习日志 第六章用堆进行动态存储

时间秒杀一切 提交于 2019-12-03 05:16:08
书中的例子是,在多座岛屿间规划航线,并记录,将岛屿作为节点,数据结构如下 typedef struct island { char *name; char *opens; char *closes; struct island *next; } island; 注意,递归结构(含有指向相同类型的指针)不能为匿名结构,结构中相同类型的指针,在c语法中不允许通过别名来声明它。 创建create,display,release函数 create: island *create(char *name) { island *i = malloc(sizeof(island)); i->name = strdup(name); i->opens = "09:00"; i->closes = "17:00"; i->next = NULL; return i; } 分配sizeof(island)大小的堆内存,并将地址给i,malloc的返回值是void*类型 ,可以充当任何类型指针赋值操作的右值,但是有的编译器可能会警告。 给成员赋值:i->name=strdup(name);strdup的含义是在内存中拷贝name,并返回地址,返回值类型为char* ,之所以这么做,是因为name只是用做接收输入的字符串,在内存中的位置固定,且内容会不断更新,如果直接使用name,那么就会有多个节点(i-