普通队列: 先进先出, 后进后出
priority queue(优先队列): 出队顺序与入队顺序无关; 和优先级相关
二叉堆
叶子节点: 一棵树当中没有子结点(即度为0)的结点称为叶子节点,简称“叶子”
从数组下标1开始存储, 最后一个非叶子节点的索引: count/2
从数组下标0开始存储,最后一个非叶子节点的索引: (count-1)/2
数组实现二叉堆
public class MaxHeap {
private int count;
private int capacaity;
private int[] data;
public MaxHeap(int capacity){
data = new int[capacity+1];
this.capacaity = capacity;
}
public int size(){
return count;
}
boolean isEmpty(){
return count == 0 ;
}
public void insert(int item){
if(count+1 > capacaity)
return;
// 从数组下标为1的位置开始插入元素
data[count+1] = item;
count++;
shiftUp(count);
}
// 取出最大的值
public int extractMax(){
if(count < 1)
return -1;
int ret = data[1];
data[1] = data[count]; // 将最后一个元素放在第一个元素的位置上
count--;
shiftDown(1);
return ret;
}
private void shiftDown(int k){
while(2*k <= count){
int j = 2*k; // 在此轮循环中,data[k]和data[j]交换位置
// 判断是否有右孩子
if(j+1<=count && data[j] < data[j+1]){
j = j+1;
}
if(data[k] >= data[j]){
break;
}
int temp = data[k];
data[k] = data[j];
data[j] = temp;
k = j;
}
}
private void shiftUp(int k){
while(k > 1 && (data[k/2] < data[k])){
int temp = data[k/2];
data[k/2] = data[k];
data[k] = temp;
k = k/2;
}
}
public void printMaxHeap(){
for(int i=1; i<=count; i++){
System.out.println("下标"+i+" ="+data[i]);
}
}
public static void main(String[] args){
MaxHeap maxHeap = new MaxHeap(100);
for(int i=0; i<15; i++){
maxHeap.insert(i);
}
System.out.println(maxHeap.size());
maxHeap.printMaxHeap();
System.out.println(maxHeap.extractMax());
maxHeap.printMaxHeap();
}
}
排序算法的稳定性
索引堆
package com.heap;
/// 索引最大堆
public class IndexMaxHeap {
private int count; // 元素个数
private int capacaity; // 元素容量
private int[] data; // 存储数据
private int[] indexs; // 存储数据的索引
public IndexMaxHeap(int capacity){
data = new int[capacity+1];
indexs = new int[capacity+1];
this.capacaity = capacity;
}
public int size(){
return count;
}
boolean isEmpty(){
return count == 0 ;
}
// 传入的i对用户而言,是从0索引开始的
public void insert(int i, int item){
if(count+1 > capacaity)
return;
if(i+1 < 1 || i+1 > capacaity)
return;
// 从数组下标为1的位置开始插入元素
data[i+1] = item;
indexs[count+1] = i+1;
count++;
shiftUp(count);
}
public int extractMax(){
if(count < 1)
return -1;
int ret = data[indexs[1]];
indexs[1] = indexs[count];
count--;
shiftDown(1);
return ret;
}
private void shiftDown(int k){
while(2*k <= count){
int j = 2*k; // 在此轮循环中,data[k]和data[j]交换位置
// 判断是否有右孩子
if(j+1<=count && data[indexs[j]] < data[indexs[j+1]]){
j = j+1;
}
if(data[indexs[k]] >= data[indexs[j]]){
break;
}
int temp = indexs[k];
indexs[k] = indexs[j];
indexs[j] = temp;
k = j;
}
}
private void shiftUp(int k){
while(k > 1 && (data[indexs[k/2]] < data[indexs[k]])){
int temp = indexs[k/2];
indexs[k/2] = indexs[k];
indexs[k] = temp;
k = k/2;
}
}
public void printMaxHeap(){
System.out.println("===");
for(int i=1; i<=count; i++){
System.out.println("下标"+i+" ="+data[i]);
}
}
public void printMaxIndexHeap(){
System.out.println("===");
for(int i=1; i<=count; i++){
System.out.println("下标"+i+" ="+data[indexs[i]]);
}
}
public static void main(String[] args){
IndexMaxHeap maxHeap = new IndexMaxHeap(100);
for(int i=0; i<15; i++){
maxHeap.insert(i, (int)(Math.random() * 100));
}
System.out.println(maxHeap.size());
maxHeap.printMaxIndexHeap();
maxHeap.printMaxHeap();
int max = maxHeap.extractMax();
System.out.println("max="+max);
maxHeap.printMaxIndexHeap();
// System.out.println(maxHeap.extractMax());
// maxHeap.printMaxIndexHeap();
//
//
// int[] arr = {5,4,10,2,12,7,9};
// maxHeap.printMaxHeap();
}
}