java实现堆
java实现小顶堆,堆是优先队列的底层数据结构
import com.google.common.collect.Lists; import lombok.Data; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * 如果根节点所在下标是0,则父节点下标i,左孩子下标2i+1,右孩子2i+2 * 如果根节点所在下标是1,则父节点下标i,左孩子下标2i,右孩子2i+1 * 因为我们用的是ArrayList,所有根节点下标为0 * * @param <T> */ @Data @NoArgsConstructor public class MHeap<T extends Comparable<T>> { private final int capacity = 100; private List<T> items = new ArrayList<T>(capacity); @Override public String toString() { return "MHeap{" + "items=" + items + '}'; } /** * 传入list构建堆 * * @param items */ public MHeap(List<T> items) { for (T item : items) { insert(item); } } public boolean isEmpty() { return items.isEmpty(); } public void insert(T data) { items.add(data); floatUp(data); } /** * 上浮:指定元素与父节点做比较,小于父节点就上浮, * 一直上浮到它应在的位置 */ private void floatUp(T data) { int child = items.size() - 1; int parent = (child - 1) / 2; //小则上浮 while (data.compareTo(items.get(parent)) < 0) { items.set(child, items.get(parent)); child = parent; parent = parent / 2; if (child == 0) { break; } } items.set(child, data); } /** * 1.先拿到最小值,暂存等待返回 * 2.获取最后一个节点last的数据e * 3.e数据放在根节点可能不一定最小,对比根的孩子节点逐级下沉,让根最小的孩子上浮 * 4.把原来最后的节点last删掉 * * @return */ public T pop() { T t = items.get(0); int last = items.size() - 1; T e = items.get(last); sinkDown( e); items.remove(last); return t; } /** * 下沉:根节点下沉到它应该的位置 */ private void sinkDown(T data) { int size = items.size(); //当前根 int parent = 0; //当前根的左孩子 int child = parent * 2 + 1; //循环条件是还没有越界 while (child < size) { //判断根是否有右孩子,假如右孩子更小,拿到更小的孩子,等待与根节点对比 if (child + 1 < size && items.get(child + 1).compareTo(items.get(child)) < 0) { child = child + 1; } //父节点小于最小的子节点,则不用动了 if (data.compareTo(items.get(child)) < 0) { break; } //父节点大于最小的孩子,则最小的孩子上浮到根节点 items.set(parent, items.get(child)); parent = child; child = parent * 2 + 1; } items.set(parent, data); } public static void main(String[] args) { List<Integer> ints = Lists.newArrayList(); Random rand = new Random(); for (int i = 10; i > 0; i--) { int i1 = rand.nextInt(100); ints.add(i1); } System.out.println(ints); MHeap<Integer> m = new MHeap<>(ints); while (!m.isEmpty()) { System.out.println(m.pop()); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗