排序 -- 堆排序

堆排序

堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

最大堆的添加元素和删除元素过程

在这里插入图片描述

java代码实现


import java.util.Random;

public class MaxHeap<E extends Comparable<E>> {
    private Array<E> arr;

    public MaxHeap() {
    }

    public MaxHeap(int capactiy) {
        this.arr = new Array<>(capactiy);
    }

    public MaxHeap(E[] arr) {
        this.arr = new Array<>(arr);
        for (int i = parent(this.arr.getData_size() - 1); i >= 0; i--) {
            siftDown(i);
        }
    }

    public static void main(String[] args) {

        int n = 100;

        int capacity = n;

        Random random = new Random();
        Integer[] ts = new Integer[n];
        for (int i = 0; i < n; i++) {
            int a = random.nextInt(100);
            ts[i] = a;
        }
        MaxHeap<Integer> maxHeap = new MaxHeap<>(ts);
        Object[] ss = maxHeap.sort();

        for (int i = 0; i < ss.length; i++) {
            ts[i] = Integer.parseInt(ss[i].toString());
        }

        for (int i = 0; i < ts.length; i++) {
            System.out.println(ts[i]);
        }
        //maxHeap.printStrust();


    }
//    public static void main(String[] args) {
//
//        int n = 100;
//
//        int capacity = 37;
//        MaxHeap<Integer> maxHeap = new MaxHeap<>(capacity);
//        Random random = new Random();
//        for (int i = 0; i < n; i++) {
//            int a = random.nextInt(100);
//            maxHeap.add(a);
//            // System.out.println("add : "+a);
//            // maxHeap.printStrust();
//        }
//
//        int[] arr = new int[capacity];
//        for (int i = 0; i < capacity; i++) {
//            System.out.println("=======================================================");
//            maxHeap.printStrust();
//            arr[i] = maxHeap.extractMax();
//            System.out.println("---------删除---" + arr[i] + "-----------------");
//            maxHeap.printStrust();
//        }
//
//
//        for (int i = 1; i < capacity; i++)
//            if (arr[i - 1] < arr[i])
//                throw new IllegalArgumentException("Error");
//
//        System.out.println("Test MaxHeap completed.");
//
//    }


    /**
     * ***堆排序***
     */
    public Object[] sort() {
        Object[] arr = new Object[this.getSize()];
        int size = this.getSize();
        for (int i = 0; i < size; i++) {
            arr[i] = this.extractMax();
        }
        return arr;
    }

    /**
     * 获得堆中元素的个数
     *
     * @return
     */
    public int getSize() {
        return this.arr.getData_size();
    }

    /**
     * 获得堆是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        return this.arr.isEmpty();
    }

    /**
     * 获得父节点的索引
     *
     * @param index
     * @return
     */
    private int parent(int index) {
        if (index == 0) {
            throw new IllegalArgumentException("Index=0 doesn't have parent ");
        }
        return (index - 1) / 2;
    }

    /**
     * 获得左孩子的索引
     *
     * @param index
     * @return
     */
    private int leftChild(int index) {
        return index * 2 + 1;
    }

    /**
     * 获得右孩子的索引
     *
     * @param index
     * @return
     */
    private int rightChild(int index) {
        return index * 2 + 2;
    }

    /**
     * 在堆底添加元素
     *
     * @param e
     */
    public void add(E e) {
        this.arr.addLast(e);
        shiftUp(this.getSize() - 1);
    }

    private void shiftUp(int index) {
        while (index > 0 && this.arr.get(this.parent(index)).compareTo(this.arr.get(index)) < 0) {
            this.arr.swap(this.parent(index), index);
            index = this.parent(index);
        }
    }

    /**
     * 获得堆中的最大的元素
     *
     * @return
     */
    public E findMax() {
        if (this.arr.getData_size() == 0) {
            throw new IllegalArgumentException("FindMax failed. the heap is empty");
        }
        return arr.get(0);
    }

    /**
     * 取出堆中最大的元素
     */
    public E extractMax() {
        E max = this.findMax();
        arr.swap(0, this.arr.getData_size() - 1);
        arr.removeLast();
        this.siftDown(0);
        return max;
    }

    private void siftDown(int index) {
        while (this.leftChild(index) < this.getSize()) {
            int leftIndex = this.leftChild(index);
            int rightIndex = leftIndex + 1;
            if (rightIndex < this.getSize() && this.arr.get(rightIndex).compareTo(this.arr.get(leftIndex)) > 0) {
                leftIndex = rightIndex;
            }
            if (this.arr.get(index).compareTo(this.arr.get(leftIndex)) >= 0) {
                return;
            }
            this.arr.swap(index, leftIndex);
            index = leftIndex;
        }
    }


    public void printStrust() {
        System.out.println();
        System.out.println(this.arr.get(0));
        int i = 1;
        while (true) {
            int len = power(i);
            int left = power(i) - 1;
            for (int j = 0; j < len; j++) {
                if (j + left >= this.getSize()) {
                    System.out.println();
                    return;
                }
                System.out.print(this.arr.get(j + left) + "\t");
            }
            i++;
            System.out.println();
        }

    }

    private int power(int p) {
        int ss = 1;
        for (int i = 0; i < p; i++) {
            ss *= 2;
        }
        return ss;
    }

    /**
     * 底层的数组
     *
     * @param <E>
     */
    private class Array<E> {
        private E[] data;
        private int data_size;
        private int capacity;

        public Array(E[] data) {
            this.data = data;
            this.data_size = data.length;
            this.capacity = this.data_size;
        }

        public Array(int capacity) {
            this.capacity = capacity;
            this.data = (E[]) new Object[capacity];
            this.data_size = 0;
        }

        /**
         * 获得数组的长度
         *
         * @return
         */
        public int getData_size() {
            return this.data_size;
        }

        public boolean isEmpty() {
            return this.data_size == 0;
        }

        /**
         * 在数组尾部添加元素
         *
         * @param e
         */
        public void addLast(E e) {
            if (this.data_size == this.capacity) {
                this.data_size--;
            }
            this.data[data_size] = e;

            this.data_size++;
        }


        /**
         * 获得 索引为index 的元素
         *
         * @param index
         * @return
         */
        public E get(int index) {
            if (index < 0 || index > this.data_size) {
                throw new IllegalArgumentException("Get failed. illegal index. ");
            }
            return this.data[index];
        }

        public E removeLast() {
            this.data_size--;
            return this.data[this.data_size];
        }

        public void swap(int i, int j) {
            E ss = this.data[i];
            this.data[i] = this.data[j];
            this.data[j] = ss;
        }

    }

}


堆排序

 /**
 * 堆排序
 */
public Object[] sort() {
    Object[] arr = new Object[this.getSize()];
    int size = this.getSize();
    for (int i = 0; i < size; i++) {
        arr[i] = this.extractMax();
    }
    return arr;
}

测试结果

99
98
97
97
97
94
94
93
92
92
90
90
90
89
88
87
87
87
86
86
86
84
83
83
83
80
79
77
75
74
74
74
71
70
68
68
68
65
65
63
61
60
59
59
58
57
55
55
54
52
51
47
47
47
47
46
46
45
45
45
44
42
42
40
40
33
33
28
27
25
25
24
23
22
19
18
18
18
17
15
14
14
13
13
11
11
9
9
9
7
5
5
4
3
3
3
2
2
2
0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值