数据结构与算法之高级排序(希尔/堆)<十一>

来源:互联网 发布:linux强制退出vi 编辑:程序博客网 时间:2024/06/05 08:02

基础排序
数据结构与算法之基础排序(冒泡/插入/选择)<十>

希尔排序

希尔排序又称为缩小增量排序。该算法是一个泛化的插入排序,插入排序在序列几乎有序的情况下非常有效。希尔排序利用此特性,分多路并使用不同的间距进行插入排序,当间距为1是则就是简单的插入排序,本质上希尔排序是插入排序的简单拓展 优点    对中等大小的序列非常有效     是所有已知O(n^2)排序算法中最快的     相对简单的排序算法 缺点     较大序列不是个好的选择    不及 归并 堆 快速排序有效     明显比 归并 堆 快速 排序慢 算法    选择合适的间距 将序列分成n路    每路使用插入排序    重复上述过程直至间距为1

堆排序

堆排序是一种基于比较的排序算法,该算法同时属于选择排序。虽然在大多数计算机上的运行效率低于快速排序。但是堆排序最大的优势是在最坏情况下O(nlogn) 

关于堆的基础知识参考数据结构与算法之优先队列<九>

以下算法实现仅供参考若有错误欢迎指正

希尔排序

public void sortByShell2(int[] a) {        int d = SIZE;        while (true) {            // 将数组分成d路然后每列进行插入排序            d = d / 2;            // 遍历所有路   每路进行插入排序            for (int j = d; j < arr.length; j++) {                // 若第i个元素大于i-1元素,该位置元素位置正确。小于的话,后移空出位置                if (a[j] < a[j - d]) {                    //下个元素位置                    int n = j - d;                    // 复制为哨兵,即存储待排序元素                    int x = a[j];                     // 先后移 空出位置                    a[j] = a[j - d];                     // 循环查找插入位置 直至找到或者到头                    while (n >= d && x < a[n - d]) {                         a[n] = a[n - d];                        //下个元素位置                        n = n - d;                     }                    // 插入到正确位置                    a[n] = x;                 }            }            // 步长为1时便是插入排序了 排序也就完成了            if (d == 1) {                break;            }        }    }

堆排序

    // 调整堆父节点小    public void adjustHeap(int[] heap, int node, int length) {        // 保存被调整的节点        int temp = heap[node];        // 利用完全二叉树的特殊性,父节点与子节点的关系child=father*2+1        int child = node * 2 + 1;        while (child < length) {            // 如果存在右孩子且右孩子小于左孩子            if ((child + 1) < length && heap[child] < heap[child + 1]) {                // 选择小的孩子                ++child;            }            // 如果父节点大于孩子中最小的            if (heap[node] < heap[child]) {                heap[node] = heap[child];                // 向下继续调整                node = child;                child = node * 2 + 1;            } else {                break;            }            // 调整完毕 找到了正确位置            heap[node] = temp;        }    }    // 建立堆    public void buildHeap(int[] arr, int length) {        // 根据child=node*2+1可以算出数列中最后一个节点        for (int node = (length - 1) / 2; node >= 0; --node) {            // 从下自上将所有的节点调整一遍            adjustHeap(arr, node, length);        }    }    // 将创建好的堆进行堆排序    public void sortByHeap(int[] array, int length) {        buildHeap(array, length);        int temp;        // 将数组遍历从尾部到顶依次与根节点互换        for (int i = length - 1; i > 0; --i) {            temp = array[i];            array[i] = array[0];            array[0] = temp;            // 将根节点替换后从上向下调整            adjustHeap(array, 0, i);        }    }

到此希尔排序和堆排序介绍完毕

下一篇 数据结构与算法之高级排序(快速/归并)<十二>

1 0
原创粉丝点击