堆排序与归并排序

 

 

//每次将堆顶元素与最后的元素交换

public class HeapSort

{

    public static void heapSort(DataWrap[] data)

    {

       System.out.println("开始排序");

       int arrayLength = data.length;

       //循环建堆

       for (int i = 0; i < arrayLength - 1 ; i++ )//n-1次循环

       {

           //建堆

           builMaxdHeap(data , arrayLength - 1 - i);

           //交换堆顶和最后一个元素

           swap(data , 0 , arrayLength - 1 - i);

           System.out.println(java.util.Arrays.toString(data));

       }

    }

    //data数组从0lastIndex建大顶堆

    private static void builMaxdHeap(DataWrap[] data , int lastIndex)

    {

       //lastIndex处节点(最后一个节点)的父节点开始

       for (int i = (lastIndex - 1) / 2 ; i >= 0  ; i--)

       {

           //k保存当前正在判断的节点

           int k = i;

           //如果当前k节点的子节点存在

           while (k * 2 + 1 <= lastIndex)

           {

              //k节点的左子节点的索引

              int biggerIndex = 2 * k  + 1;

              //如果biggerIndex小于lastIndex,即biggerIndex + 1

              //代表的k节点的右子节点存在

              if (biggerIndex < lastIndex)

              {

                   //如果右子节点的值较大

                  if(data[biggerIndex].compareTo(data[biggerIndex + 1]) < 0)

                  {

                     //biggerIndex总是记录较大子节点的索引

                     biggerIndex++;

                  }

              }

              //如果k节点的值小于其较大子节点的值

              if(data[k].compareTo(data[biggerIndex]) < 0)

              {

                  //交换它们

                  swap(data , k , biggerIndex);

                  //biggerIndex赋给k,开始while循环的下一次循环,

                  //重新保证k节点的值大于其左、右子节点的值。

                  k = biggerIndex;

              }

              else

              {

                  break;

              }

           }

       }

    }

    //交换data数组中ij两个索引处的元素

    private static void swap(DataWrap[] data , int i , int j)

    {

       DataWrap tmp = data[i];

       data[i] = data[j];

       data[j] = tmp;

}

public static void main(String[] args)

    {

       DataWrap[] data = {

           new DataWrap(21 , ""),

           new DataWrap(30 , ""),

           new DataWrap(49 , ""),

           new DataWrap(30 , "*"),

           new DataWrap(21 , "*"),

           new DataWrap(16 , ""),

           new DataWrap(9 , "")

       };

       System.out.println("排序之前:/n"

           + java.util.Arrays.toString(data));

       heapSort(data);

       System.out.println("排序之后:/n"

           + java.util.Arrays.toString(data));

    }

}

 

 

归并排序

public class MergeSort

{

    //利用归并排序算法对数组data进行排序

    public static void mergeSort(DataWrap[] data)

    {

       //归并排序

       sort(data , 0 , data.length - 1);

    }

    /**

     * 将索引从leftright范围的数组元素进行归并排序

     * @param data 待排序的数组

     * @param left 待排序的数组的第一个元素索引

     * @param right 待排序的数组的最后一个元素的索引

     */

    private static void sort(DataWrap[] data

        , int left, int right)

    {

       if (left < right)

       {

           //找出中间索引

           int center = (left + right) / 2;

           //对左边数组进行递归

           sort(data, left, center);

           //对右边数组进行递归

           sort(data, center + 1, right);

           //合并

           merge(data, left, center, right);

       }

    }

    /**

     * 将两个数组进行归并,归并前两个数组已经有序,归并后依然有序。

     * @param data 数组对象

     * @param left 左数组的第一个元素的索引

     * @param center 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引

     * @param right 右数组的最后一个元素的索引

     */

    private static void merge(DataWrap[] data

       , int left, int center, int right)

    {

       //定义一个与待排序序列长度相同的临时数组

       DataWrap[] tmpArr = new DataWrap[data.length];

       int mid = center + 1;

       //third记录中间数组的索引

       int third = left;

       int tmp = left;

       while (left <= center && mid <= right)

       {

           //从两个数组中取出小的放入中间数组

           if (data[left].compareTo(data[mid]) <= 0)

           {

              tmpArr[third++] = data[left++];

           }

           else

           {

              tmpArr[third++] = data[mid++];

           }

       }

       //剩余部分依次放入中间数组

       while (mid <= right)

       {

           tmpArr[third++] = data[mid++];

       }

       while (left <= center)

       {

           tmpArr[third++] = data[left++];

       }

       //将中间数组中的内容复制拷回原数组

       //(leftright范围的内容复制回原数组)

       while (tmp <= right)

       {

           data[tmp] = tmpArr[tmp++];

       }

    }

    public static void main(String[] args)

    {

       DataWrap[] data = {

           new DataWrap(9 , ""),

           new DataWrap(-16 , ""),

           new DataWrap(21 , "*"),

           new DataWrap(23 , ""),

           new DataWrap(-30 , ""),

           new DataWrap(-49 , ""),

           new DataWrap(21 , ""),

           new DataWrap(30 , "*"),

           new DataWrap(30 , "")

       };

       System.out.println("排序之前:/n"

           + java.util.Arrays.toString(data));

       mergeSort(data);

       System.out.println("排序之后:/n"

           + java.util.Arrays.toString(data));

    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值