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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java 优先队列从小到大,优先队列(Java)

發(fā)布時間:2025/3/19 java 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 优先队列从小到大,优先队列(Java) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

優(yōu)先隊列(底層結構為最大堆)

普通的隊列是一種先進先出的數(shù)據(jù)結構,元素在隊列尾追加,而從隊列頭刪除。在優(yōu)先隊列中,元素被賦予優(yōu)先級。當訪問元素時,具有最高優(yōu)先級的元素最先刪除。優(yōu)先隊列具有最高級先出 (first in, largest out)的行為特征。通常采用堆數(shù)據(jù)結構來實現(xiàn)。

優(yōu)先隊列主要是出隊操作與普通隊列不同,隊列中元素會有優(yōu)先級之分,每次出隊的元素是優(yōu)先級最高的元素。

最大堆(二叉堆)

最大堆是堆的兩種形式之一。

根結點(亦稱為堆頂)的關鍵字是堆里所有結點關鍵字中最大者,稱為大根堆,又稱最大堆(大頂堆)。

大根堆要求根節(jié)點的關鍵字既大于或等于左子樹的關鍵字值,又大于或等于右子樹的關鍵字值。

Arr.java(動態(tài)數(shù)組)

//動態(tài)數(shù)組

public class Arr {

private E[] data;// 創(chuàng)建一個數(shù)組

private int size;// 數(shù)組中元素個數(shù)

// 自定義構造器初始化數(shù)組 capacity數(shù)組的長度

public Arr(int capacity) {

// TODO Auto-generated constructor stub

data = (E[]) new Object[capacity];

size = 0;

}

// 默認構造方法 capacity數(shù)組的長度=10

public Arr() {

// TODO Auto-generated constructor stub

this(10);

}

// 根據(jù)傳來的數(shù)組生成動態(tài)數(shù)組

public Arr(E[] arr) {

data = (E[]) new Object[arr.length];

for (int i = 0; i < arr.length; i++) {

data[i] = arr[i];

}

size = arr.length;

}

// 獲取數(shù)組個數(shù)

public int getSize() {

return size;

}

// 獲取數(shù)組長度

public int getCapacity() {

return data.length;

}

// 判斷數(shù)組是否為空

public boolean isEmpty() {

return size == 0;

}

// 數(shù)組中添加元素 index是插入元素的位置,e是插入的元素,時間復雜度為O(n)

public void add(int index, E e) {

if (index < 0 || index > size) {

try {

throw new Exception("數(shù)組排列要求不能有空");

} catch (Exception e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

}

// 數(shù)組擴容

if (size == data.length) {

try {

resize(2 * data.length); // 這里是擴容為原數(shù)組的2倍,Arraylist是擴容1.5倍

} catch (Exception e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

}

for (int i = size - 1; i >= index; i--) {

data[i + 1] = data[i];

}

data[index] = e;

size++;

}

// 數(shù)組擴容或者縮容,時間復雜度為O(n)

private void resize(int newcapcatity) {

// TODO Auto-generated method stub

E[] newData = (E[]) new Object[newcapcatity];

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

newData[i] = data[i];

}

data = newData;

}

// 在數(shù)組末尾添加元素,時間復雜度為O(1)

public void addLast(E e) {

add(size, e);

}

// 在數(shù)組首部添加元素,時間復雜度為O(n)

public void addFirst(E e) {

add(0, e);

}

// 重寫toString 使用字符串拼接

@Override

public String toString() {

StringBuilder res = new StringBuilder();

res.append(String.format("Array:size = %d, capacity = %d\n", size, data.length));

res.append('[');

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

res.append(data[i]);

if (i != size - 1) {

res.append(',');

}

}

res.append(']');

return res.toString();

}

public E getLast() {

return get(size - 1);

}

public E getFirst() {

return get(0);

}

// 獲取index位置的數(shù)組元素,時間復雜度為O(1)

E get(int index) {

if (index < 0 || index >= size) {

try {

throw new Exception("index非法");

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

return data[index];

}

// 修改數(shù)組元素,時間復雜度為O(1)

void set(int index, E e) {

if (index < 0 || index >= size) {

try {

throw new Exception("index非法");

} catch (Exception e3) {

// TODO Auto-generated catch block

e3.printStackTrace();

}

}

data[index] = e;

}

// 查詢是否包含數(shù)組元素e,時間復雜度為O(n)

public boolean contains(E e) {

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

if (data[i].equals(e))

return true;

}

return false;

}

// 查找數(shù)組元素e,時間復雜度為O(n)

public int find(E e) {

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

if (data[i].equals(e))

return i;// 返回元素e的位置

}

return -1;// 找不到元素e,返回-1

}

// 刪除指定位置index的數(shù)組元素,時間復雜度為O(n)

public E remove(int index) {

if (index < 0 || index >= size) {

try {

throw new Exception("index非法");

} catch (Exception e3) {

// TODO Auto-generated catch block

e3.printStackTrace();

}

}

// 縮容

if (size == data.length / 2) {

resize(data.length / 2);

}

E ret = data[index];

for (int i = index + 1; i < size; i++) {

data[i - 1] = data[i];

}

size--;

data[size] = null;

return ret;// 返回刪除的元素

}

// 數(shù)組刪除首個元素,時間復雜度為O(n)

public E removeFirst() {

return remove(0);

}

// 數(shù)組刪除最后一個元素,時間復雜度為O(1)

public E removeLast() {

return remove(size - 1);

}

// 數(shù)組刪除元素e,時間復雜度為O(n)

public void removeElement(E e) {

int index = find(e);

if (index != -1) {

remove(index);

} else {

System.out.println("數(shù)組中沒有元素e");

}

}

// 元素交換

public void swap(int i, int j) {

if (i < 0 || i >= size || j >= size || j < 0)

try {

throw new Exception("元素越界");

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

E t = data[i];

data[i] = data[j];

data[j] = t;

}

}

MaxHeap.java(最大堆)

//最大堆 以動態(tài)數(shù)組為底層

public class MaxHeap> {

private Arr data;

public MaxHeap(int capacity) {

// TODO Auto-generated constructor stub

data = new Arr<>(capacity);

}

public MaxHeap() {

// TODO Auto-generated constructor stub

data = new Arr<>();

}

// 構造函數(shù) 將任意數(shù)組整理成最大堆的形狀

public MaxHeap(E[] arr) {

data = new Arr<>(arr);// 根據(jù)傳來的數(shù)組生成動態(tài)數(shù)組

for (int i = parent(arr.length - 1); i >= 0; i--) {

siftDown(i);// 從最后一個非葉子節(jié)點進行下沉,一直到根節(jié)點

}

}

public int size() {

return data.getSize();

}

public boolean isEmpty() {

return data.isEmpty();

}

// 返回二叉樹的數(shù)組表示中,一個索引所表示的元素的父親節(jié)點的索引

private int parent(int index) {

if (index == 0) {

try {

throw new Exception("根節(jié)點沒有父節(jié)點");

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

return (index - 1) / 2;

}

// 獲取左孩子節(jié)點的索引

private int leftChild(int index) {

return 2 * index + 1;

}

// 獲取右孩子節(jié)點的索引

private int rightChild(int index) {

return 2 * index + 2;

}

// 向堆中添加元素

public void add(E e) {

data.addLast(e);// 在數(shù)組末尾添加元素e

siftUp(data.getSize() - 1);// 元素上浮

}

// 堆中元素上浮

private void siftUp(int k) {

// TODO Auto-generated method stub

while (k > 0 && data.get(parent(k)).compareTo(data.get(k)) < 0) {

data.swap(k, parent(k));// 與父節(jié)點進行交換

k = parent(k);// k變化到父節(jié)點,準備下一輪循環(huán)

}

}

// 取出堆中最大元素

public E findMax() {

if (data.getSize() == 0)

try {

throw new Exception("堆為空");

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return data.get(0);

}

// 取出堆中最大元素

public E extractMax() {

E ret = findMax();

data.swap(0, data.getSize() - 1);

data.removeLast();

siftDown(0);

return ret;

}

// 元素下沉

private void siftDown(int k) {

// TODO Auto-generated method stub

while (leftChild(k) < data.getSize()) {

int j = leftChild(k);

if (j + 1 < data.getSize() && data.get(j + 1).compareTo(data.get(j)) > 0) {

j = rightChild(k);

// data[j]是左孩子和右孩子中的最大值

if (data.get(k).compareTo(data.get(j)) >= 0)// 左右孩子的最大值與索引為k的元素進行比較

break;// 如果索引為k的元素大于左右孩子的最大值,即符合堆的性質(zhì)

data.swap(k, j);// 否則進行交換

k = j;// 元素k的索引變?yōu)閖,準備下次循環(huán)

}

}

}

// 取出堆中的最大元素,并且替換成元素e

public E replace(E e) {

E ret = findMax();// 找到最大元素

data.set(0, e);// 將e替換成最大元素的位置

siftDown(0);// 進行下沉

return ret;

}

}

最大堆中常用的方法

replace:取出最大元素后,放入一個新元素

實現(xiàn)1:可以先使用extractMax方法取出最大元素,再使用add方法,兩次O(logn)的操作

實現(xiàn)2:可以直接將堆頂元素替換以后Sift Down,一次O(logn)的操作

heapify:將任意數(shù)組整理成最大堆的形狀

實現(xiàn)1:將n個元素逐個插入一個空的最大堆中,算法復雜度是O(nlogn)

實現(xiàn)2:heapify的過程,算法復雜度為O(n)(上述代碼中使用構造函數(shù)public MaxHeap(E[] arr)完成heapify的操作)

Queue.java(隊列接口)

public interface Queue {

void enqueue(E e);//入隊

E dequeue();//出隊

E getFront();//獲取隊首元素

int getSize();//獲取隊列中元素個數(shù)

boolean isEmpty();//判斷隊列是否為空

}

PriorityQueue.java(優(yōu)先隊列)

//優(yōu)先隊列,底層結構為最大堆 實現(xiàn)隊列接口

public class PriorityQueue> implements Queue {

private MaxHeap maxHeap;

public PriorityQueue() {

// TODO Auto-generated constructor stub

maxHeap = new MaxHeap<>();

}

@Override

public void enqueue(E e) {

// TODO Auto-generated method stub

maxHeap.add(e);

}

@Override

public E dequeue() {

// TODO Auto-generated method stub

return maxHeap.extractMax();//去除堆中最大元素

}

@Override

public E getFront() {

// TODO Auto-generated method stub

return maxHeap.findMax();//最大堆的堆頂元素

}

@Override

public int getSize() {

// TODO Auto-generated method stub

return maxHeap.size();

}

@Override

public boolean isEmpty() {

// TODO Auto-generated method stub

return maxHeap.isEmpty();

}

}

悅悅的狗子

發(fā)布了27 篇原創(chuàng)文章 · 獲贊 6 · 訪問量 2493

私信

關注

標簽:index,優(yōu)先,Java,隊列,元素,int,data,public,size

來源: https://blog.csdn.net/weixin_44190113/article/details/104137448

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的java 优先队列从小到大,优先队列(Java)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。