• 大顶堆第二弹----堆排序(递归实现)


      1 package com.datastruct;
      2 
      3 import java.util.ArrayList;
      4 import java.util.Arrays;
      5 
      6 public class BigHeap {
      7     
      8     
      9     
     10     /*
     11      *交换堆中的两个元素 
     12      */
     13     private void swap(ArrayList<Integer> heapList,int srcIndex,int dstIndex)
     14     {
     15         int tmp = heapList.get(srcIndex);
     16         
     17         heapList.set(srcIndex,heapList.get(dstIndex));
     18         heapList.set(dstIndex, tmp);
     19         
     20     }
     21     
     22     /*
     23      *将指定元素的位置进行上移操作 
     24      */
     25     private void HeapUp(ArrayList<Integer> heapList,int index)
     26     {
     27                 
     28         if(index > 1)
     29         {
     30             int parent = index / 2;
     31             int parentVal = heapList.get(parent).intValue();
     32             int indexVal =  heapList.get(index).intValue();
     33             
     34             if(indexVal > parentVal)
     35             {
     36                 swap(heapList,parent,index);
     37                 HeapUp(heapList,parent);
     38             }
     39             
     40         }
     41     }
     42     
     43     /*
     44      *将指定元素的位置进行下移操作 
     45      */
     46     private void HeapDown(ArrayList<Integer> heapList,int index)
     47     {
     48         int heapSize = heapList.size(); //这里进行了重复的计算,可以将作为形参传入,或者将该函数,写成非递归形式
     49         
     50         if(index > heapSize - 1)
     51         {//节点不存在
     52             return;
     53         }
     54         
     55         int child = index * 2; //左孩子节点
     56         
     57         if(child > (heapSize - 2))
     58         {//当前节点为叶子节点,不能进行下移操作,直接返回
     59          //-2是由于最后一个元素已经是要删除的节点,不在计算范围之内
     60             return;
     61         }
     62         else if(child < heapSize - 2) 
     63         {//有两个孩子节点
     64              if(heapList.get(child).intValue() < heapList.get(child + 1).intValue())
     65              {
     66                  child++; //右孩子结点值大,作为新的父节点
     67              }
     68         }
     69         
     70         if(heapList.get(child).intValue() > heapList.get(index).intValue())
     71         {//孩子节点的值大,进行下移
     72             swap(heapList,child, index);
     73             HeapDown(heapList,child);//继续进行下移操作
     74         }
     75         
     76     }
     77     
     78     /*
     79      *向大顶堆中插入一个元素
     80      */
     81     public void HeapInsert(ArrayList<Integer> heapList,int value)
     82     {
     83         int heapSize = heapList.size();
     84         
     85         if(heapSize == 0)
     86         {//第一个元素不为堆中的元素,跳过
     87             heapList.add(-100);
     88         }
     89         
     90         heapList.add(value);
     91         heapSize++; //添加新元素后,改变堆的大小
     92         
     93         HeapUp(heapList,heapSize - 1);
     94     }
     95     
     96     /*
     97      *从大顶堆中删除一个元素 
     98      */
     99     public void HeapDelete(ArrayList<Integer> heapList,int value)
    100     {
    101         int index = 1,heapSize = heapList.size();
    102         for(; index < heapSize; index++)
    103         {
    104             if(heapList.get(index).intValue() == value)
    105             {
    106                 break;
    107             }
    108         }
    109         
    110         if (index >= heapSize)
    111         {//元素不存在
    112             return;
    113         }
    114         
    115         heapList.set(index, heapList.get(heapSize-1)); //将最后一个叶子节点值赋值到当前节点
    116         HeapDown(heapList,index); 
    117         
    118         int parent = index / 2;
    119         
    120         if(parent > 0 && ( heapList.get(index).intValue() > (Integer)heapList.get(parent).intValue() ))
    121         {//如果下移操作后该元素大于父节点还要进行上移
    122             HeapUp(heapList,index);
    123         }
    124         
    125         heapList.remove(heapSize - 1);
    126     }
    127     
    128     /*
    129      *调整堆结构    
    130      */
    131     public void heapAdjust(ArrayList<Integer>heapList,int index,int end)
    132     {
    133         int child = -1,heapSize = heapList.size();
    134         
    135         end = end > heapSize - 1 ? heapSize - 1 : end; //确保结束正确
    136         
    137         while(index <= end / 2)
    138         {//只需调整非叶子节点
    139             child = index * 2; //左孩子节点
    140             if(child + 1 <= end && (heapList.get(child+1).intValue() > heapList.get(child).intValue()) )
    141             {
    142                 child += 1; //右孩子节点值大右孩子节点上移
    143             }
    144             
    145             if(heapList.get(child).intValue() > heapList.get(index).intValue())
    146             {
    147                 swap(heapList, child, index);
    148                 index = child;
    149             }
    150             else
    151             {
    152                 break;
    153             }
    154         }
    155     }
    156     
    157     
    158     /*
    159      * 初始化时调整堆结构
    160      * 由于堆是完全二叉树结构,所以只有前一半节点是非叶子节点
    161      */
    162     public void heapInitAdjust(ArrayList<Integer> heapList)
    163     {
    164         int heapSize = heapList.size();
    165         
    166         for(int i = heapSize / 2; i > 0; i--)
    167         {
    168             heapAdjust(heapList, i, heapSize - 1);
    169         }    
    170         
    171     }
    172     
    173     /*
    174      * 堆排序
    175      * 将大顶堆堆顶元素和最后一个元素交换,调整剩下元素的对结构
    176      * 直到调整到最后一个元素就排好序
    177      */
    178     public void heapSort(ArrayList<Integer>heapList)
    179     {
    180         int heapSize = heapList.size();
    181         
    182         for(int i = heapSize - 1; i > 0; i--)
    183         {
    184             swap(heapList, 1, i); //交换堆顶和最后一个元素
    185             heapAdjust(heapList, 1, i - 1);
    186         }
    187     }
    188     
    189     /*
    190      *  打印堆元素
    191      */
    192     public void PrintHeap(ArrayList<Integer> heapList)
    193     {
    194         for(int i = 1; i < heapList.size(); i++)
    195         {
    196             System.out.print(heapList.get(i) + " ");
    197         }
    198         
    199         System.out.println();
    200     }
    201     
    202     
    203     
    204     public static void main(String args[])
    205     {
    206         ArrayList<Integer> heapList = new ArrayList<>(Arrays.asList(null,1,3,4,5,8,2,7));
    207         
    208         BigHeap bigHeap = new BigHeap();
    209         
    210         bigHeap.heapInitAdjust(heapList);
    211         bigHeap.PrintHeap(heapList);
    212         
    213         bigHeap.HeapInsert(heapList, 6);
    214         bigHeap.PrintHeap(heapList);
    215         
    216         bigHeap.heapSort(heapList);
    217         bigHeap.PrintHeap(heapList);
    218     }
    219 }
  • 相关阅读:
    Make a web page as screensaver
    python写入sqlserver中文乱码问题
    单片机中的ROM,RAM和FLASH的作用
    单片机STM32F4系统内部中断和外部中断优先级问题
    单片机AHB和APB
    嵌入式编程中一些常用的转换函数
    'AVStream::codec': 被声明为已否
    Python安装Python_snappy安装失败
    .net core 数据库问题
    .net 5.0 中 CrystalQuartz 增加授权校验
  • 原文地址:https://www.cnblogs.com/daimadebanyungong/p/4971896.html
Copyright © 2020-2023  润新知