zoukankan      html  css  js  c++  java
  • 大顶堆第二弹----堆排序(递归实现)

      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 }
  • 相关阅读:
    【HTML5 绘图与动画】使用canvas
    【H5新增元素和文档结构】新的全局属性 1. contentEditable 可编辑内容 2. contextmenu 快捷菜单 3. data 自定义属性 4. draggable 可拖动 5. dropzone 拖动数据 6. hidden 隐藏 7. spellcheck 语法检查 8. translate 可翻译
    【H5新增元素和文档结构】完善旧元素 1. a 超链接 2. ol 有序列表 3. dl 定义列表 4. cite 引用文本 5. small 小号字体 6. iframe 浮动框架 7. script 脚本
    【H5新增元素和文档结构】新的语义信息 1. address 2. time 3. figure 跟 figcaption 4. details 和 summary 5. mark 6. progress 7. meter 8. dialog 9.bdi 10. wbr 11. ruby、rt、rp 12. command
    【H5新增元素跟文档结构】新的文档结构 1. article 文章块 2. section 区块 3. nav 导航条 4. aside 辅助栏 5. main 主要区域 6. header 标题栏 7. hgroup 标题组 8. footer 页脚栏
    5_PHP数组_3_数组处理函数及其应用_9_数组集合运算函数
    【华为云技术分享】鲲鹏弹性云服务器GCC交叉编译环境搭建指南
    【华为云技术分享】7 分钟全面了解位运算
    【华为云技术分享】Linux内核编程环境 (1)
    【华为云技术分享】华为云MySQL 8.0正式商用,全新增强版开源利器强势来袭
  • 原文地址:https://www.cnblogs.com/daimadebanyungong/p/4971896.html
Copyright © 2011-2022 走看看