堆排序与归并排序

来源:互联网 发布:自我测评软件 编辑:程序博客网 时间:2024/06/05 00:39

堆实际上是一颗完全二叉树,其任何一非叶节点满足
key[ i ]<=key[ 2i+1 ]&&key[ 2i+2 ]或者相反,也就说任何非叶节点的关键字不大于或者不小于其左右孩子节点的关键字

堆排序的思想

1、建立堆 ,此时得到的是无序堆2、堆顶与堆的最后一个元素交换位置,此时得到是新的无序堆和新的有序堆

代码实现

public class HeapSort {    public static void main(String[] args) {        int[] a = { 1, 3, 15, 25, 379, 63, 37, 21, 12 };        int arrayLength = a.length;        for (int i = 0; i < arrayLength; i++) {            // 循环建堆            buildMaxHeap(a, arrayLength - 1 - i);// 从最后元素开始            // 交换堆顶和最后一个元素            swap(a, 0, arrayLength - 1 - i);            System.out.println(Arrays.toString(a));        }    }    private static void swap(int[] a, int i, int j) {          int temp=a[i];          a[i]=a[j];          a[j]=temp;    }    private static void buildMaxHeap(int[] a, int 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 (a[biggerIndex] < a[biggerIndex + 1]) {                        // biggerIndex总是记录较大子节点的索引                        biggerIndex++;                        // 所以最大的肯定是biggerIndex这个索引                    }                }                // 如果k节点的值小于其较大子节点的值就交换他们,保存父节点比子节点大                if (a[k] < a[biggerIndex]) {                    // 交换他们                    swap(a, k, biggerIndex);//                  k = biggerIndex;                } else {                    break;                }            }        }    }}

归并排序

代码实现
1、先排序左部分
2、再排序右部分
3、合并左右部分(1、对比左右把较小的数移到新数组 2、把左边剩余的数移到新数组 3、把右边剩余的数移到新数组 4、遍历用新数组覆盖a旧数组 )

public class RadixSort {    //将两个有序表合成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的    //然后再把有序子序列合并为整体有序序列    public static int[] sort(int[] a,int low,int high){        int mid=(low+high)/2;        if(low<high){            //左边            sort(a,low,mid);            //右边            sort(a,mid+1,high);            //左右合并            merge(a,low,mid,high);        }        return a;    }    public static void merge(int[] a,int low,int mid,int high){        int[] temp=new int[high-low+1];        int i=low;//左指针        int j=mid+1;//右指针        int k=0;        //把较小的数先移到新数组        while(i<=mid&&j<=high){            //{8,7,6,9,1,3}            if(a[i]<a[j]){                temp[k++]=a[i++];            }else{                temp[k++]=a[j++];            }        }        //把左边剩余的数移到数组        while(i<=mid){            temp[k++]=a[i++];        }        //把右边剩余的数移到数组        while(j<=high){            temp[k++]=a[j++];        }        //把新数组的数覆盖a数组        for(int b=0;b<temp.length;b++){            a[b+low]=temp[b];        }//      System.out.println(Arrays.toString(a));    }    public static void main(String[] args) {        int[] a = { 1, 3, 15, 25, 379, 63, 37, 21, 12 };//      int arrayLength = a.length;        System.out.println(Arrays.toString(RadixSort.sort(a, 0, a.length-1)));    }}
0 0
原创粉丝点击