Skip to content

Commit 6939177

Browse files
committed
堆排序、topK
1 parent 5c6bbcb commit 6939177

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package com.algorithm.study.demo.datastructure.tree;
2+
3+
import com.alibaba.fastjson.JSON;
4+
5+
/**
6+
* 堆
7+
* 堆就是一颗完全二叉树
8+
* 堆中每一个节点的值都必须大于等于(或者小于等于)其子树(左右子节点)中每个节点的值。
9+
* 堆顶存储的就是最大值或者最小值
10+
* 用数组存储非常节省存储空间,下标为id的节点的左子节点就是i*2的节点,右子节点的下标为i*2+1。父节点就是i/2的节点。
11+
*
12+
* @Author: liuxun
13+
* @CreateDate: 2019/1/31 上午10:30
14+
* @Version: 1.0
15+
*/
16+
public class Heap {
17+
private int[] data;
18+
private int count;//堆中元素的个数
19+
private int capacity;//堆容量
20+
21+
/**
22+
* 初始化堆
23+
* @param capacity
24+
*/
25+
public Heap(int capacity){
26+
this.capacity=capacity;
27+
data=new int[capacity];
28+
count=0;
29+
}
30+
31+
/**
32+
* 往堆中插入数据
33+
* 从下往上的方法堆化
34+
* @param d
35+
*/
36+
public void insert(int d){
37+
if (count>=capacity) return;//堆满了
38+
count++;//从下标为1开始填充数据
39+
data[count]=d;
40+
int i=count;
41+
while (i/2>0 && data[i]>data[i/2]){
42+
//交换数据
43+
swap(data,i,i/2);
44+
i=i/2;//切到父节点
45+
}
46+
}
47+
48+
private static void swap(int[] a,int i,int n) {
49+
int temp=a[i];
50+
a[i]=a[n];
51+
a[n]=temp;
52+
}
53+
54+
/**
55+
* 删除堆顶元素
56+
* 把最后一个元素放到对顶,然后从上到下的方法堆化。
57+
*/
58+
public void removeMax(){
59+
data[1]=data[count];
60+
count--;
61+
int i=1;
62+
heapify(data,count,i);
63+
}
64+
65+
private static void buildHeap(int[] a, int n) {
66+
for (int i = n/2; i >= 1; --i) {
67+
heapify(a, n, i);
68+
}
69+
System.out.println(JSON.toJSONString(a));
70+
}
71+
72+
private static void heapify(int[] a, int n, int i) {
73+
while (true) {
74+
int maxPos = i;
75+
if (i*2 <= n && a[i] < a[i*2]) maxPos = i*2;
76+
if (i*2+1 <= n && a[maxPos] < a[i*2+1]) maxPos = i*2+1;
77+
if (maxPos == i) break;
78+
swap(a, i, maxPos);
79+
i = maxPos;
80+
}
81+
}
82+
83+
// n 表示数据的个数,数组 a 中的数据从下标 1 到 n 的位置。
84+
public static void sort(int[] a, int n) {
85+
buildHeap(a, n);//构建堆
86+
int k = n;
87+
while (k > 1) {
88+
swap(a, 1, k);//堆顶跟最后一个元素交换
89+
--k;//每次k-1,也就去取出
90+
heapify(a, k, 1);//1-k堆化
91+
}
92+
System.out.println(JSON.toJSONString(a));
93+
}
94+
95+
96+
public static void main(String[] args) {
97+
// Heap heap=new Heap(6);
98+
// for (int i=1;i<=5;i++){
99+
// heap.insert(i);
100+
// }
101+
// System.out.println(heap.count);
102+
103+
int[] d = new int[]{0, 5, 2, 1, 4, 3};
104+
sort(d,d.length-1);
105+
}
106+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.algorithm.study.demo.datastructure.tree;
2+
3+
import com.alibaba.fastjson.JSON;
4+
5+
import java.util.PriorityQueue;
6+
7+
/**
8+
* @Author: liuxun
9+
* @CreateDate: 2019/1/30 下午8:10
10+
* @Version: 1.0
11+
*/
12+
public class TopkCount {
13+
/**
14+
* 求数据中前K大数据
15+
*
16+
* @param data
17+
* @param k
18+
* @return
19+
*/
20+
public static int[] topk(int[] data, int k) {
21+
PriorityQueue<Integer> queue = new PriorityQueue<>(k);
22+
23+
for (int i = 0; i < data.length; i++) {
24+
if (queue.size() < k) {
25+
queue.offer(data[i]);
26+
} else {
27+
int value = queue.peek();
28+
// 如果发现数据比堆顶元素大,则加入到小顶堆中
29+
if (data[i] > value) {
30+
queue.poll();//删除
31+
queue.offer(data[i]);
32+
}
33+
}
34+
}
35+
36+
int[] result = new int[k];
37+
int index = 0;
38+
// 遍历完成后,小顶堆的数据就为需要求得的topk的数据
39+
while (!queue.isEmpty()) {
40+
result[index++] = queue.poll();
41+
}
42+
43+
return result;
44+
}
45+
46+
public static void main(String[] args) {
47+
System.out.println(JSON.toJSONString(topk(new int[]{1,2,3,4,5},2)));
48+
}
49+
}

0 commit comments

Comments
 (0)