" />

最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入了解Java數(shù)據(jù)結(jié)構(gòu)和算法之堆

 更新時(shí)間:2022年01月21日 15:19:26   作者:YSOcean  
這篇文章主要為大家介紹了Java數(shù)據(jù)結(jié)構(gòu)和算法之堆 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

1、堆的定義

①、它是完全二叉樹,除了樹的最后一層節(jié)點(diǎn)不需要是滿的,其它的每一層從左到右都是滿的。注意下面兩種情況,第二種最后一層從左到右中間有斷隔,那么也是不完全二叉樹。

②、它通常用數(shù)組來實(shí)現(xiàn)?! ?/p>

這種用數(shù)組實(shí)現(xiàn)的二叉樹,假設(shè)節(jié)點(diǎn)的索引值為index,那么:

節(jié)點(diǎn)的左子節(jié)點(diǎn)是 2*index+1,

節(jié)點(diǎn)的右子節(jié)點(diǎn)是 2*index+2,

節(jié)點(diǎn)的父節(jié)點(diǎn)是 (index-1)/2。

③、堆中的每一個(gè)節(jié)點(diǎn)的關(guān)鍵字都大于(或等于)這個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)的關(guān)鍵字。

這里要注意堆和前面說的二叉搜索樹的區(qū)別,二叉搜索樹中所有節(jié)點(diǎn)的左子節(jié)點(diǎn)關(guān)鍵字都小于右子節(jié)點(diǎn)關(guān)鍵字,在二叉搜索樹中通過一個(gè)簡單的算法就可以按序遍歷節(jié)點(diǎn)。但是在堆中,按序遍歷節(jié)點(diǎn)是很困難的,如上圖所示,堆只有沿著從根節(jié)點(diǎn)到葉子節(jié)點(diǎn)的每一條路徑是降序排列的,指定節(jié)點(diǎn)的左邊節(jié)點(diǎn)或者右邊節(jié)點(diǎn),以及上層節(jié)點(diǎn)或者下層節(jié)點(diǎn)由于不在同一條路徑上,他們的關(guān)鍵字可能比指定節(jié)點(diǎn)大或者小。所以相對于二叉搜索樹,堆是弱序的。

2、遍歷和查找

前面我們說了,堆是弱序的,所以想要遍歷堆是很困難的,基本上,堆是不支持遍歷的。

對于查找,由于堆的特性,在查找的過程中,沒有足夠的信息來決定選擇通過節(jié)點(diǎn)的兩個(gè)子節(jié)點(diǎn)中的哪一個(gè)來選擇走向下一層,所以也很難在堆中查找到某個(gè)關(guān)鍵字。

因此,堆這種組織似乎非常接近無序,不過,對于快速的移除最大(或最?。┕?jié)點(diǎn),也就是根節(jié)點(diǎn),以及能快速插入新的節(jié)點(diǎn),這兩個(gè)操作就足夠了。

3、移除

移除是指刪除關(guān)鍵字最大的節(jié)點(diǎn)(或最小),也就是根節(jié)點(diǎn)。

根節(jié)點(diǎn)在數(shù)組中的索引總是0,即maxNode = heapArray[0];

移除根節(jié)點(diǎn)之后,那樹就空了一個(gè)根節(jié)點(diǎn),也就是數(shù)組有了一個(gè)空的數(shù)據(jù)單元,這個(gè)空單元我們必須填上。

第一種方法:將數(shù)組所有數(shù)據(jù)項(xiàng)都向前移動(dòng)一個(gè)單元,這比較費(fèi)時(shí)。

第二種方法:

  • ①、移走根
  • ②、把最后一個(gè)節(jié)點(diǎn)移動(dòng)到根的位置
  • ③、一直向下篩選這個(gè)節(jié)點(diǎn),直到它在一個(gè)大于它的節(jié)點(diǎn)之下,小于它的節(jié)點(diǎn)之上為止。

具體步驟如下:

圖a表示把最后一個(gè)節(jié)點(diǎn)移到根節(jié)點(diǎn),圖b、c、d表示將節(jié)點(diǎn)向下篩選到合適的位置,它的合適位置在最底層(有時(shí)候可能在中間),圖e表示節(jié)點(diǎn)在正確位置的情景。

注意:向下篩選的時(shí)候,將目標(biāo)節(jié)點(diǎn)和其子節(jié)點(diǎn)比較,誰大就和誰交換位置。

4、插入

插入節(jié)點(diǎn)也很容易,插入時(shí),選擇向上篩選,節(jié)點(diǎn)初始時(shí)插入到數(shù)組最后第一個(gè)空著的單元,數(shù)組容量大小增一。然后進(jìn)行向上篩選的算法。

注意:向上篩選和向下不同,向上篩選只用和一個(gè)父節(jié)點(diǎn)進(jìn)行比較,比父節(jié)點(diǎn)小就停止篩選了。

5、完整的Java堆代碼

首先我們要知道用數(shù)組表示堆的一些要點(diǎn)。若數(shù)組中節(jié)點(diǎn)的索引為x,則:

節(jié)點(diǎn)的左子節(jié)點(diǎn)是 2*index+1,

節(jié)點(diǎn)的右子節(jié)點(diǎn)是 2*index+2,

節(jié)點(diǎn)的父節(jié)點(diǎn)是 (index-1)/2。

注意:"/" 這個(gè)符號,應(yīng)用于整數(shù)的算式時(shí),它執(zhí)行整除,且得到是是向下取整的值。

package com.ys.tree.heap;
 
public class Heap {
     
    private Node[] heapArray;
    private int maxSize;
    private int currentSize;
     
    public Heap(int mx) {
        maxSize = mx;
        currentSize = 0;
        heapArray = new Node[maxSize];
    }
     
    public boolean isEmpty() {
        return (currentSize == 0)? true : false;
    }
     
    public boolean isFull() {
        return (currentSize == maxSize)? true : false;
    }
     
    public boolean insert(int key) {
        if(isFull()) {
            return false;
        }
        Node newNode = new Node(key);
        heapArray[currentSize] = newNode;
        trickleUp(currentSize++);
        return true;
    }
    //向上調(diào)整
    public void trickleUp(int index) {
        int parent = (index - 1) / 2; //父節(jié)點(diǎn)的索引
        Node bottom = heapArray[index]; //將新加的尾節(jié)點(diǎn)存在bottom中
        while(index > 0 && heapArray[parent].getKey() < bottom.getKey()) {
            heapArray[index] = heapArray[parent];
            index = parent;
            parent = (parent - 1) / 2;
        }
        heapArray[index] = bottom;
    }
     
    public Node remove() {
        Node root = heapArray[0];
        heapArray[0] = heapArray[--currentSize];
        trickleDown(0);
        return root;
    }
    //向下調(diào)整
    public void trickleDown(int index) {
        Node top = heapArray[index];
        int largeChildIndex;
        while(index < currentSize/2) { //while node has at least one child
            int leftChildIndex = 2 * index + 1;
            int rightChildIndex = leftChildIndex + 1;
            //find larger child
            if(rightChildIndex < currentSize &&  //rightChild exists?
                    heapArray[leftChildIndex].getKey() < heapArray[rightChildIndex].getKey()) {
                largeChildIndex = rightChildIndex;
            }
            else {
                largeChildIndex = leftChildIndex;
            }
            if(top.getKey() >= heapArray[largeChildIndex].getKey()) {
                break;
            }
            heapArray[index] = heapArray[largeChildIndex];
            index = largeChildIndex;
        }
        heapArray[index] = top;
    }
    //根據(jù)索引改變堆中某個(gè)數(shù)據(jù)
    public boolean change(int index, int newValue) {
        if(index < 0 || index >= currentSize) {
            return false;
        }
        int oldValue = heapArray[index].getKey();
        heapArray[index].setKey(newValue);
        if(oldValue < newValue) {
            trickleUp(index);
        }
        else {
            trickleDown(index);
        }
        return true;
    }
     
    public void displayHeap() {
        System.out.println("heapArray(array format): ");
        for(int i = 0; i < currentSize; i++) {
            if(heapArray[i] != null) {
                System.out.print(heapArray[i].getKey() + " ");
            }
            else {
                System.out.print("--");
            }
        }
    }
}
class Node {
    private int iData;
    public Node(int key) {
        iData = key;
    }
     
    public int getKey() {
        return iData;
    }
     
    public void setKey(int key) {
        iData = key;
    }
}

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • idea?2024使用Maven創(chuàng)建Java?Web項(xiàng)目詳細(xì)圖文教程

    idea?2024使用Maven創(chuàng)建Java?Web項(xiàng)目詳細(xì)圖文教程

    這篇文章主要給大家介紹了關(guān)于idea?2024使用Maven創(chuàng)建Java?Web項(xiàng)目的相關(guān)資料,介紹了如何使用Maven創(chuàng)建一個(gè)Spring?MVC項(xiàng)目,并配置Tomcat服務(wù)器以運(yùn)行一個(gè)簡單的Helloworld?JSP頁面,需要的朋友可以參考下
    2024-12-12
  • Java編程中的HashSet和BitSet詳解

    Java編程中的HashSet和BitSet詳解

    這篇文章主要介紹了Java編程中的HashSet和BitSet詳解的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • 關(guān)于Java如何用好線程池的方法分享(建議收藏)

    關(guān)于Java如何用好線程池的方法分享(建議收藏)

    這篇文章主要來和大家分享幾個(gè)關(guān)于Java如何用好線程池的建議,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解一下
    2023-06-06
  • java內(nèi)部類原理與用法詳解

    java內(nèi)部類原理與用法詳解

    這篇文章主要介紹了java內(nèi)部類原理與用法,結(jié)合實(shí)例形式分析了Java內(nèi)部類的概念、原理、分類及相關(guān)使用技巧,需要的朋友可以參考下
    2019-05-05
  • Quarkus集成open api接口使用swagger ui展示

    Quarkus集成open api接口使用swagger ui展示

    這篇文章主要為大家介紹了Quarkus集成open?api接口使用swagger?ui的展示示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • Java網(wǎng)絡(luò)編程之TCP程序設(shè)計(jì)

    Java網(wǎng)絡(luò)編程之TCP程序設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了Java網(wǎng)絡(luò)編程之TCP程序設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Dubbo無法訪問遠(yuǎn)程Zookeeper已注冊服務(wù)的問題解決方案

    Dubbo無法訪問遠(yuǎn)程Zookeeper已注冊服務(wù)的問題解決方案

    今天小編就為大家分享一篇關(guān)于Dubbo無法訪問遠(yuǎn)程Zookeeper已注冊服務(wù)的問題解決方案,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Java判斷多個(gè)時(shí)間段是否重合的方法小結(jié)

    Java判斷多個(gè)時(shí)間段是否重合的方法小結(jié)

    這篇文章主要為大家詳細(xì)介紹了Java中判斷多個(gè)時(shí)間段是否重合的方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-02-02
  • 介紹Java的大數(shù)類(BigDecimal)和八種舍入模式

    介紹Java的大數(shù)類(BigDecimal)和八種舍入模式

    在實(shí)際應(yīng)用中,需要對更大或者更小的數(shù)進(jìn)行運(yùn)算和處理。Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數(shù)進(jìn)行精確的運(yùn)算。本文將介紹Java中的大數(shù)類BigDecimal及其八種舍入模式,有需要的可以參考借鑒。
    2016-08-08
  • Java I/O流實(shí)例之簡歷替換

    Java I/O流實(shí)例之簡歷替換

    流是一種抽象概念,它代表了數(shù)據(jù)的無結(jié)構(gòu)化傳遞。。用來進(jìn)行輸入輸出操作的流就稱為IO流。換句話說,IO流就是以流的方式進(jìn)行輸入輸出
    2021-09-09

最新評論

银川市| 呈贡县| 岳西县| 新闻| 司法| 焦作市| 白河县| 项城市| 彭泽县| 福安市| 日土县| 泸定县| 铜陵市| 视频| 馆陶县| 中阳县| 通道| 定南县| 秦皇岛市| 北碚区| 丹巴县| 凤阳县| 新津县| 辽中县| 洛宁县| 什邡市| 鄂温| 宁国市| 轮台县| 绥中县| 咸丰县| 大荔县| 永济市| 横山县| 星座| 乐至县| 延津县| 扎兰屯市| 怀远县| 滕州市| 虹口区|