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

来源:互联网 发布:林清轩芦荟胶 知乎 编辑:程序博客网 时间:2024/05/17 02:17
  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             else151             {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 }

 

0 0
原创粉丝点击