选择排序

来源:互联网 发布:一分钱图片淘宝怎么弄 编辑:程序博客网 时间:2024/06/04 19:22

1、直接选择排序

需要进行n-1次比较
每次将i位置的元素依次与之后的所有元素进行比较,若其大于则进行位置调换

实现代码:

public class DataWrap implements Comparable<DataWrap>{    int data;    String flag;    public DataWrap(int data, String flag)    {        this.data = data;        this.flag = flag;    }    @Override    public int compareTo(DataWrap dataWrap)    {        return this.data > dataWrap.data ? 1 : (this.data == dataWrap.data ? 0                : -1);    }    public String toString()    {        return data + flag;    }}
//直接选择排序public class SelectSort{    public static void main(String[] args)    {        DataWrap[] dataWraps =        { new DataWrap(21, ""), new DataWrap(30, ""), new DataWrap(49, ""),                new DataWrap(30, "*"), new DataWrap(16, ""),                new DataWrap(9, "") };        System.out.println("排序之前:\n" + Arrays.toString(dataWraps));        selectSort(dataWraps);        System.out.println("排序之后:\n" + Arrays.toString(dataWraps));    }    public static void selectSort(DataWrap[] dataWraps)    {        System.out.println("排序开始。。。。。");        int arrayLength = dataWraps.length;        for (int i = 0; i < arrayLength - 1; i++)        {            // 保存本次比较中最小值的索引            int minIndex = i;            // 第i个数只需与后面的数比较            for (int j = i + 1; j < arrayLength; j++)            {                if (dataWraps[minIndex].compareTo(dataWraps[j]) > 0)                {                    // 将当前获得的最小值索引赋值给minIndex                    minIndex = j;                }                if (i != minIndex)                {                    DataWrap tmp = dataWraps[i];                    dataWraps[i] = dataWraps[minIndex];                    dataWraps[minIndex] = tmp;                }            }        }    }}

有n项数据,数据交换做多n-1次,但是比较次数较多,时间复杂度为O(n2)
空间复杂度为O(1)

2、堆排序

堆排序的建堆(大顶堆和小顶堆)
排序过程:

  1. 先将其转换成完全二叉树
  2. 完全二叉树的最后一个非叶子节点,也就是最后一个父节点。其索引值为(n-2)/2,如果其子节点大于它本身则与较大的子节点交换
  3. 向前处理前一个节点,直至根节点
  4. 交换堆顶和最后一个元素,将最后一个元素移除堆
  5. 重复2、3、4步骤

实现代码

//堆排序public class HeapSort{    public static void main(String[] args)    {        DataWrap[] dataWraps =        { 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" + Arrays.toString(dataWraps));        heapSort(dataWraps);        System.out.println("排序之后:\n" + Arrays.toString(dataWraps));    }    public static void heapSort(DataWrap[] dataWraps)    {        System.out.println("开始排序。。。。");        int arrayLength = dataWraps.length;        // 循环建堆        for (int i = 0; i < arrayLength - 1; i++)        {            buildMaxdHeap(dataWraps, arrayLength - 1 - i);            // 交换堆顶和最后一个元素            swap(dataWraps, 0, arrayLength - 1 - i);            System.out.println(Arrays.toString(dataWraps));        }    }    private static void buildMaxdHeap(DataWrap[] dataWraps, 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 = k * 2 + 1;                // 如果biggerIndex小于lastIndex,即biggerIndex+1                // 代表的k节点的右子节点存在                if (biggerIndex < lastIndex)                {                    // 如果右子节点的数据大                    if (dataWraps[biggerIndex]                            .compareTo(dataWraps[biggerIndex + 1]) < 0)                    {                        // 记录较大的子节点                        biggerIndex++;                    }                }                if (dataWraps[k].compareTo(dataWraps[biggerIndex]) < 0)                {                    // 交换                    swap(dataWraps, k, biggerIndex);                    // 将biggerIndex赋值给k开始下一次循环                    // 重新保证k节点的值大于其左右子节点                    k = biggerIndex;                } else                {                    break;                }            }        }    }    // 交换两个索引处元素位置    private static void swap(DataWrap[] dataWraps, int i, int j)    {        DataWrap tmp = dataWraps[i];        dataWraps[i] = dataWraps[j];        dataWraps[j] = tmp;    }}

需要进行n-1次建堆,每次建堆消耗log2n,则时间复杂度为O(nlog2n)
空间复杂度为O(1)