好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

彻底搞定堆排序:二叉堆

二叉堆

什么是二叉堆

二叉堆本质上是一种完全二叉树,它分为两个类型

最大堆:最大堆的任何一个父节点的值,都大于等于它的左、右孩子节点的值(堆顶就是整个堆的最大元素) 最小堆:最小堆的任何一个父节点的值,都小于等于它的左、右孩子节点的值(堆顶就是整个堆的最小元素)

二叉堆的根节点叫做堆顶

二叉堆的基本操作

插入节点 删除节点 构建二叉堆

这几种操作都基于堆的自我调整,所谓堆自我调整,就是把一个不符合堆的完全二叉树,调整成一个堆,下面以最小堆为例。

插入

插入节点0的过程

删除

删除节点的过程和插入的过程刚好相反,所删除的是处于堆顶的节点。例如删除1

为了维持完全二叉树的结构,把堆的最后一个元素临时补充到堆顶 删除原来10的位置 对堆顶的节点10执行下沉操作

构建

构建二叉堆,也就是把一个无序的完全二叉树调整为二叉堆,本质就是让所有的非叶子节点一次 下沉

二叉堆代码实现

二查堆虽然是一颗完全二叉树,但它的存储方式并不是链式的,而是顺序存储,换句话说,二叉堆的所有节点都存储在数组中

当父节点为parent时,左孩子为2 * parent + 1;右孩子为2 * parent + 2

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

/**

  * @author :zsy

  * @date :created 2021/5/17 9:41

  * @description:二叉堆

  */

public class heaptest {

     public static void main(string[] args) {

         int [] arr = { 1 , 3 , 2 , 6 , 5 , 7 , 8 , 9 , 10 , 0 };

         heap heap = new heap(arr);

         heap.upadjust(arr);

         system.out.println(arrays.tostring(arr));

         arr = new int []{ 7 , 1 , 3 , 10 , 5 , 2 , 8 , 9 , 6 };

         heap = new heap(arr);

         heap.buildhead();

         system.out.println(arrays.tostring(arr));

     }

}

class heap {

     private int [] arr;

     public heap( int [] arr) {

         this .arr = arr;

     }

     public void buildhead() {

         //从最后一个非叶子节点开始,依次下沉

         for ( int i = (arr.length - 2 ) / 2 ; i >= 0 ; i--) {

             downadjust(arr, i, arr.length);

         }

     }

     private void downadjust( int [] arr, int parentindex, int length) {

         int temp = arr[parentindex];

         int childrenindex = parentindex * 2 + 1 ;

         while (childrenindex < length) {

             //如果有右孩子,并且右孩子小于左孩子,那么定位到右孩子

             if (childrenindex + 1 < length && arr[childrenindex + 1 ] < arr[childrenindex]) {

                 childrenindex++;

             }

             //如果父节点小于较小孩子节点的值,直接跳出

             if (temp <= arr[childrenindex]) break ;

             //无需交换,单向赋值

             arr[parentindex] = arr[childrenindex];

             parentindex = childrenindex;

             childrenindex = 2 * childrenindex + 1 ;

         }

         arr[parentindex] = temp;

     }

     public void upadjust( int [] arr) {

         int childrenindex = arr.length - 1 ;

         int parentindex = (childrenindex - 1 ) / 2 ;

         int temp = arr[childrenindex];

         while (childrenindex > 0 && temp < arr[parentindex]) {

             //单向赋值

             arr[childrenindex] = arr[parentindex];

             childrenindex = parentindex;

             parentindex = (parentindex - 1 ) / 2 ;

         }

         arr[childrenindex] = temp;

     }

}

结果:

[0, 1, 2, 6, 3, 7, 8, 9, 10, 5]
[1, 5, 2, 6, 7, 3, 8, 9, 10]

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注的更多内容!

原文链接:https://blog.csdn.net/qq_45796208/article/details/117094130

查看更多关于彻底搞定堆排序:二叉堆的详细内容...

  阅读:15次