前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >希尔排序与堆排序

希尔排序与堆排序

作者头像
周小末天天开心
发布2023-10-16 12:17:50
1350
发布2023-10-16 12:17:50
举报
文章被收录于专栏:周小末天天开心

希尔排序

       待排序区间划分成若干个有跨度的子区间,然后进行插入排序,当最后跨度缩小到1的时候来一次完整的插入排序。

 第一次排序:length = 10; gap = a.length / 2 = 5; 将待排序的区间分成五个相同跨度的子区间。得到{49,13} {38,27} {65,49*} {97,55} {76,4}五个子区间,进行插入排序,得到排序后的区间为:{13,49} {27,38} {49*,65} {97,55} {4,76} {13,27,49*,55,4,49,38,65,97,76} 第二次排序:gap = gap / 2 = 2; 将区间分为两个子区间。得到{13,49*,4,38,97} {27, 55, 49, 65, 76}两个子区间,插入排序后得到{4,13,38,49*,97} 和 {27,49,55,65,76} {4,27,13,49,38,55,49*,65,97,76} 第三次排序:gap = gap / 2 = 1; 所以直接对{4,27,13,49,38,55,49*,65,97,76}进插入排序,就可以得到排序后的区间为{4,13,27,38,49,49*,55,65,76,97}

代码语言:javascript
复制
import java.util.Arrays;
import java.util.Scanner;

public class shellSort {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int[] a = new int[10];
        for (int i = 0; i < a.length; i++) {
            a[i] = scanner.nextInt();
        }
        shell(a);
        System.out.println(Arrays.toString(a));
    }

    public static void shell(int[] a) {
        for (int gap = a.length / 2; gap > 0 ; gap /= 2) {
            //没分一组就直接进行插入排序
            for (int i = gap; i < a.length; i++) {
                int j = i;//存放每一组中当前要处理的那个数据
                while (j - gap >= 0 && a[j - gap] >a[j]) {
                    //大的数据往后移动
                    int temp = a[j];
                    a[j] = a[j - gap];
                    a[j - gap] = temp;
                    j -= gap;//下一次继续从分组里的前一个位置开始
                }
            }

        }
    }
}

堆排序

初始数组为:int[] a = {57, 68, 59, 52, 72, 28, 96, 33, 24}; (1)用数组存储,第i个节点的叶子分别是2i+1和2i+2 (2)根的值小于(或者大于)左右子树,子树也需要满足这个定义 (3)堆看起来是一棵完全二叉树,存储却只需要用到数组即可 (4)开始建堆的时候数组顺序与二叉树层次遍历对应,逐步从非叶子节点到根调整 (5)堆排序以大根堆为例,每次堆顶和最后的那个叶子对调,保证大的放到目前堆的最后,然后把顶部元素调整好,最后就是升序排列

代码语言:javascript
复制
import java.util.Arrays;

//堆排序
public class heapSort {
    public static void main(String[] args) {
        int[] a = {57, 68, 59, 52, 72, 28, 96, 33, 24};//待排序数组的初始顺序
        heap(a);
        System.out.println(Arrays.toString(a));
    }

    public static void heap(int[] a) {
        //从倒数第一个非叶子结点开始调整,一直调整到根,让数组满足大根堆的递归定义
        for (int i = a.length / 2 - 1; i >= 0 ; i--) {//a.length / 2 - 1 是堆的最后一个非叶子结点
            //对数组的第i个元素当做根,调整的范围是目前无序的空间
            adjustHeap(a, i, a.length);//a.length 是目前无序的空间
        }
        for (int i = a.length - 1; i > 0 ; i--) {
            swap(a, 0, i);//交换数组里的根和无序堆中的最后一个数
            adjustHeap(a, 0, i);//每一轮都把前i个里最大的数放到最后,这样无序的范围都是0到i
        }
    }

    //swap方法完成数组中根和无序堆中最后一个数的交换
    private static void swap(int[] a, int root, int last) {//root为根  last为最后的数
        int temp = a[root];
        a[root] = a[last];
        a[last] = temp;
    }

    //左右子树挑大的进行交换,继续对左右子树进行调整,保证整个堆递归满足大根堆的定义
    private static void adjustHeap(int[] a, int i, int length) {
        int bak = a[i];//备份一下要调整的元素

        //开始的时候,从待调整的元素i的左子树开始 2 * i + 1,后面每次递归 2 * j + 1
        for (int j = 2 * i + 1; j < length; j = 2 * j + 1) {
            if (j + 1 < length && a[j + 1] > a[j]) {
                //j + 1为右子树,需要小于length并且让j永远都指向自己左右子树里大的那个
                j++;
            }
            if (bak < a[j]) {
                //如果bak的元素小于左右子树中大的那一个
                a[i] = a[j];//大的元素拷贝到i这个位置
                i = j;//下一次从以i为根的子树开始,让i等于这个j作为根
            }
            else break;//不小于说明位置已经调整好了
        }
        a[i] = bak;//一次性把最原始要调整的a[i]放到该放的位置
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 希尔排序
  • 堆排序
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档