日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java二叉堆_为什么二叉堆利用数组存储?

發布時間:2025/3/19 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java二叉堆_为什么二叉堆利用数组存储? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

邏輯結構最大的優勢就在于,通過數組,目標index 能推算出 父子指針的定位。

所以在上下heaptify的時候可以直接找到對應位置進行交換等操作。

現有語言里比如Java,C,C+;以java為例:

系統層面API:PriorityQueue ”優先隊列“,底層實現就是堆結構。其實就是堆實現。

但是大部分堆API都沒有提供動態修改已排序對象內部值的方法 Resign();

#舉例 已排序堆數組arr[];其中元素為Object O, 并且O包含N個屬性,比如以age屬性為例

arr[O1,O2,O3...] 這里裝著一堆object同學對象,現在以同學對象的age屬性,給arr排序

/*** 需求是,我給O3的age調整,比如改成20歲,對象要變更內部值。* 要求O3調整完畢后,提供一個方法,保證arr[]依然是排序后的堆結構。* ###動態修改,動態增刪,這種其實現實中很常見的需求。* 關鍵還在于,我們需要時間復雜度。* O(logN) 復雜度*/

- 邏輯過程簡單想一下就知道 插入一個值,然后每次O對象都要從下往上/從上往下進行heaptify這個操作,而且要進行N次

所以大部分都覺得動態修改這個代價太大。

回到正題,如果想實現O(logN)時間復雜度的堆,就需要有一個IndexMap:目的每次記錄修改前的值在堆內的哪個 ”位置“ 。

我個人認為正是由于數組的下標,標記了父子對應關系的可預見性數學方程關系:

[0,1,2,3,4,5]前提以0位置開始

1. left = 2*i + 1;

2. right = 2*i + 2;

3. root = (i - 1)/2;

才方便找到。

鏈表實現對應關系,可能會使用更多數據結構占用。

附帶數組Heap Resign();

package class04;

import java.util.ArrayList;

import java.util.Comparator;

import java.util.HashMap;

import java.util.PriorityQueue;

public class Heap {

// 堆

public static class MyHeap {

private ArrayList heap;

private HashMap indexMap;

private int heapSize;

private Comparator super T> comparator;

public MyHeap(Comparator super T> com) {

heap = new ArrayList<>();

indexMap = new HashMap<>();

heapSize = 0;

comparator = com;

}

public boolean isEmpty() {

return heapSize == 0;

}

public int size() {

return heapSize;

}

public boolean contains(T key) {

return indexMap.containsKey(key);

}

public void push(T value) {

heap.add(value);

indexMap.put(value, heapSize);

heapInsert(heapSize++);

}

public T pop() {

T ans = heap.get(0);

int end = heapSize - 1;

swap(0, end);

heap.remove(end);

indexMap.remove(ans);

heapify(0, --heapSize);

return ans;

}

public void resign(T value) {

int valueIndex = indexMap.get(value);

heapInsert(valueIndex);

heapify(valueIndex, heapSize);

}

private void heapInsert(int index) {

while (comparator.compare(heap.get(index), heap.get((index - 1) / 2)) < 0) {

swap(index, (index - 1) / 2);

index = (index - 1) / 2;

}

}

private void heapify(int index, int heapSize) {

int left = index * 2 + 1;

while (left < heapSize) {

int largest = left + 1 < heapSize && (comparator.compare(heap.get(left + 1), heap.get(left)) < 0)

? left + 1

: left;

largest = comparator.compare(heap.get(largest), heap.get(index)) < 0 ? largest : index;

if (largest == index) {

break;

}

swap(largest, index);

index = largest;

left = index * 2 + 1;

}

}

private void swap(int i, int j) {

T o1 = heap.get(i);

T o2 = heap.get(j);

heap.set(i, o2);

heap.set(j, o1);

indexMap.put(o1, j);

indexMap.put(o2, i);

}

}

public static class Student {

public int classNo;

public int age;

public int id;

public Student(int c, int a, int i) {

classNo = c;

age = a;

id = i;

}

}

public static class StudentComparator implements Comparator {

@Override

public int compare(Student o1, Student o2) {

return o1.age - o2.age;

}

}

public static void main(String[] args) {

Student s1 = null;

Student s2 = null;

Student s3 = null;

Student s4 = null;

Student s5 = null;

Student s6 = null;

s1 = new Student(2, 50, 11111);

s2 = new Student(1, 60, 22222);

s3 = new Student(6, 10, 33333);

s4 = new Student(3, 20, 44444);

s5 = new Student(7, 72, 55555);

s6 = new Student(1, 14, 66666);

PriorityQueue heap = new PriorityQueue<>(new StudentComparator());

heap.add(s1);

heap.add(s2);

heap.add(s3);

heap.add(s4);

heap.add(s5);

heap.add(s6);

while (!heap.isEmpty()) {

Student cur = heap.poll();

System.out.println(cur.classNo + "," + cur.age + "," + cur.id);

}

System.out.println("===============");

MyHeap myHeap = new MyHeap<>(new StudentComparator());

myHeap.push(s1);

myHeap.push(s2);

myHeap.push(s3);

myHeap.push(s4);

myHeap.push(s5);

myHeap.push(s6);

while (!myHeap.isEmpty()) {

Student cur = myHeap.pop();

System.out.println(cur.classNo + "," + cur.age + "," + cur.id);

}

System.out.println("===============");

s1 = new Student(2, 50, 11111);

s2 = new Student(1, 60, 22222);

s3 = new Student(6, 10, 33333);

s4 = new Student(3, 20, 44444);

s5 = new Student(7, 72, 55555);

s6 = new Student(1, 14, 66666);

heap = new PriorityQueue<>(new StudentComparator());

heap.add(s1);

heap.add(s2);

heap.add(s3);

heap.add(s4);

heap.add(s5);

heap.add(s6);

s2.age = 6;

s4.age = 12;

s5.age = 10;

s6.age = 84;

while (!heap.isEmpty()) {

Student cur = heap.poll();

System.out.println(cur.classNo + "," + cur.age + "," + cur.id);

}

System.out.println("===============");

s1 = new Student(2, 50, 11111);

s2 = new Student(1, 60, 22222);

s3 = new Student(6, 10, 33333);

s4 = new Student(3, 20, 44444);

s5 = new Student(7, 72, 55555);

s6 = new Student(1, 14, 66666);

myHeap = new MyHeap<>(new StudentComparator());

myHeap.push(s1);

myHeap.push(s2);

myHeap.push(s3);

myHeap.push(s4);

myHeap.push(s5);

myHeap.push(s6);

s2.age = 6;

myHeap.resign(s2);

s4.age = 12;

myHeap.resign(s4);

s5.age = 10;

myHeap.resign(s5);

s6.age = 84;

myHeap.resign(s6);

while (!myHeap.isEmpty()) {

Student cur = myHeap.pop();

System.out.println(cur.classNo + "," + cur.age + "," + cur.id);

}

// 對數器

System.out.println("test begin");

int maxValue = 100000;

int pushTime = 1000000;

int resignTime = 100;

MyHeap test = new MyHeap<>(new StudentComparator());

ArrayList list = new ArrayList<>();

for(int i = 0 ; i < pushTime; i++) {

Student cur = new Student(1,(int) (Math.random() * maxValue), 1000);

list.add(cur);

test.push(cur);

}

for(int i = 0 ; i < resignTime; i++) {

int index = (int)(Math.random() * pushTime);

list.get(index).age = (int) (Math.random() * maxValue);

test.resign(list.get(index));

}

int preAge = Integer.MIN_VALUE;

while(test.isEmpty()) {

Student cur = test.pop();

if(cur.age < preAge) {

System.out.println("Oops!");

}

preAge = cur.age;

}

System.out.println("test finish");

}

}

總結

以上是生活随笔為你收集整理的java二叉堆_为什么二叉堆利用数组存储?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。