java 堆排,优先级队列,归并排序
堆排
堆排是基于二叉树而得来的
例如:对一个数组

可以转为二叉树: 
二叉树特性父节点为 i , 左叶子节点为2i+1;右叶子节点为2i+2;
步骤分解:
1. 先从第一个非叶子节点(即下标为(length-1-1)/2 即6)开始,把大的值往父节点调整
经过一轮调整之后 最大的值此时在根节点处(即arr[0]):

2.根节点数和数组最后一个元素进行交换,此时数组中最大的值在最后一位,一个有序元素产生,
3.反复进行此过程,再次交换时和未被排序的最后一个元素交换,直至数组有序。
堆排的时间复杂度:无论哪种情况 都是 nO(log2n)
空间复杂度:O(1)
稳定性:不稳定。
源码
private static void heapSort(int[] arr) {
int n = arr.length - 1;
// 从第一个非叶子节点开始,把大值往父节点调整
for (int i = (n - 1) / 2; i >= 0; --i) {
adjust(arr, i, arr.length);
}
for (int i = n; i >= 0; --i) {
//0 <=> i 它们的值进行交换
int tmp = arr[0];
arr[0] = arr[i];
arr[i] = tmp;
//再继续进行堆的调整 adjust
adjust(arr,0,i);
}
}
/**
* 堆的调整函数,把每一个节点,和其左右孩子节点的最大值放到当前节点处
*
* @param arr
* @param i
* @param length
*/
private static void adjust(int[] arr, int i, int length) {
int temp = arr[i];
for (int j = 2 * i + 1; j < length; j = 2 * j + 1) {
if (j+1<length&&arr[j + 1] > arr[j]) {
j++;
}
if (arr[j] > temp) {
arr[i] = arr[j];
i=j;
}else break;
}
arr[i]=temp;
}
优先级队列
优先级队列=>基于大根堆实现
public class PriorityQueue<T extends Comparable<T>> {
private T[] queue;
private int index; // 记录有效元素的个数
public PriorityQueue(){
this.queue = (T[])new Comparable[10];
}
// 入优先级队列
public void push(T val){
if(full()){
this.queue = Arrays.copyOf(queue, queue.length*2);
}
if(index == 0){
queue[index] = val;
} else {
siftUp(index, val); // 新插入的元素,要进行堆的上浮操作
}
index++;
}
/**
* 堆的上浮函数
* @param i
* @param val
*/
private void siftUp(int i, T val) {
while(i > 0){
int j = (i-1)/2;
if(queue[j].compareTo(val) < 0){
queue[i] = queue[j];
i = j;
} else {
break;
}
}
queue[i] = val;
}
// 出优先级队列
public T pop(){
if(empty())
return null;
T oldval = queue[0];
--index;
if(index > 0){
siftDown(0, queue[index]); // 删除元素,进行堆的下沉操作
}
return oldval;
}
/**
* 堆的下沉函数
* @param i
* @param val
*/
private void siftDown(int i, T val) {
for(int j=2*i+1; j<index; j=j*2+1){
if(j+1 < index && queue[j+1].compareTo(queue[j]) > 0){
j++;
}
if(queue[j].compareTo(val) > 0){
queue[i] = queue[j];
i = j;
} else {
break;
}
}
queue[i] = val;
}
boolean full(){
return index == queue.length;
}
boolean empty(){
return index == 0;
}
归并排序
归并排序为外部排序,适用于内存有限制,数据无法一次性放入内存的情况
基本思路:采用分治法,将数组分为A B两部分,可以将A,B组各自再分成二组。依次递归,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再递归合并相邻的二个小组就可以了。
时间复杂度:O(nlog2n)
空间复杂度:O(n)
稳定性:稳定
源码
//i=0;j=arr.length-1.
private static void mergeSort(int[] arr, int i, int j) {
if(i < j)
{
int mid = (i+j)/2;
/**
* 以下的操作,先进行数组划分,直到划分为单个元素以后,逐级向上回溯
* 的时候,进行合并操作
*/
mergeSort(arr, i, mid);
mergeSort(arr, mid+1, j);
merge(arr, i, j); // 合并两个有序的序列
}
} /**
* 合并两个有序的序列
* @param arr
* @param low
* @param high
*/
private static void merge(int[] arr, int low, int high) {
int[] tmp = new int[high-low+1];
int mid = (low+high)/2; // i-mid mid+1-j
int i=low; // [i, mid]区间
int j=mid+1; // [mid+1, high]区间
int idx=0; // 3 12 5 8
while(i <= mid && j <= high){
if(arr[i] > arr[j]){
tmp[idx++] = arr[j++];
} else {
tmp[idx++] = arr[i++];
}
} while(i <= mid){ //
tmp[idx++] = arr[i++];
} while(j <= high){
tmp[idx++] = arr[j++];
} // 把tmp里面合并的有序段再写回arr的[low,high]
for(int k=low; k<=high; ++k){
arr[k] = tmp[k-low];
}
}
java 堆排,优先级队列,归并排序的更多相关文章
- 笔试算法题(57):基于堆的优先级队列实现和性能分析(Priority Queue based on Heap)
议题:基于堆的优先级队列(最大堆实现) 分析: 堆有序(Heap-Ordered):每个节点的键值大于等于该节点的所有孩子节点中的键值(如果有的话),而堆数据结构的所有节点都按照完全有序二叉树 排.当 ...
- java PriorityBlockingQueue 基于优先级队列,的读出操作可以阻止.
java PriorityBlockingQueue 基于优先级队列.的读出操作可以阻止. package org.rui.thread.newc; import java.util.ArrayLis ...
- Java笔记(十)堆与优先级队列
优先级队列 一.PriorityQueue PriorityQueue是优先级队列,它实现了Queue接口,它的队列长度 没有限制,与一般队列的区别是,它有优先级概念,每个元素都有优先 级,队头的元素 ...
- Java集合总结(三):堆与优先级队列
堆 满二叉树:满二叉树是指,除了最后一层外,每个节点都有两个孩子,而最后一层都是叶子节点,都没有孩子. 完全二叉树:完全二叉树不要求最后一层是满的,但如果不满,则要求所有节点必须集中在最左边,从左到右 ...
- java 中PriorityQueue优先级队列使用方法
1.前言 优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果想实现按照自己的意愿进行优 ...
- java中PriorityQueue优先级队列使用方法
优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果不提供Comparator的话,优先 ...
- 《转》JAVA中PriorityQueue优先级队列使用方法
该文章转自:http://blog.csdn.net/hiphopmattshi/article/details/7334487 优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最 ...
- 【转】java中PriorityQueue优先级队列使用方法
优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果不提供Comparator的话,优先 ...
- 【数据结构与算法Python版学习笔记】树——利用二叉堆实现优先级队列
概念 队列有一个重要的变体,叫作优先级队列. 和队列一样,优先级队列从头部移除元素,不过元素的逻辑顺序是由优先级决定的. 优先级最高的元素在最前,优先级最低的元素在最后. 实现优先级队列的经典方法是使 ...
随机推荐
- Centos7下Firewalld防火墙配置命令
前 言 服务端口日常被拦截,记录一下常用的命令便于查询 Firewalld服务管理 查看防火墙状态 1 systemctl status firewalld 开机启用/禁用防火墙 1 s ...
- 常用css3属性的ie兼容查看
记录一下关于css3的各种常用属性对ie各版本浏览器的兼容程度: 最低可兼容ie7 最低可兼容ie8 最低可兼容ie9 最低可兼容ie10 position:fixed clip E:first-le ...
- 第八篇 编写spider爬取jobbole的所有文章
通过scrapy的Request和parse,我们能很容易的爬取所有列表页的文章信息. PS:parse.urljoin(response.url,post_url)的方法有个好处,如果post_ur ...
- JQuery on绑定click无效的的bug解决办法?
如果你在移动端使用zepto.js, touch 来代替click事件,那就没有上述标题的问题了.如果你仍然使用了click,在点击事件中苹果机就可能出现无效的结果. 第一种方法: 解决的方法很巧妙, ...
- 将时间 '2018-08-06T10:00:00.000Z' 格式转化为本地时间
参考:https://blog.csdn.net/sxf_123456/article/details/81582964 参考模板: from datetime import datetime, ti ...
- mongo数组修改器—$push、$ne、$addtoset、$pop、$pull
这几个方法也很有意思 $push 像已有的数组末尾加入一个元素,要是元素不存在,就会创建一个新的元素,如果元素存在了,就会再添加一个一模一样的元素,会造成元素的重复,所以在使用的时候,要确保该元素不存 ...
- C语言结构体内存分配详情
#include <stdio.h> int main() { /*************************************************** * * 结构体内存 ...
- 网络编程之 OSI七层协议
内容目录: 1.软件开发架构 2.OSI七层协议 3.每层协议介绍 1.软件开发架构 c/s架构: c:客户端 s:服务端 b/s架构: b:浏览器 s:服务器 本质:b/s其实也是c/s 2.OSI ...
- ubuntu QT安装以及配置交叉编译环境
我的环境:ubuntu14.04 64位 1.下载Qt: 上网搜索 qt-opensource-linux-x64-5.3.0.run下载有好多百度云盘 要么在官网下载追新版本http://down ...
- 数组foreach
简单使用 代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...