Java数据结构之排序(头歌平台,详细注释)

这篇具有很好参考价值的文章主要介绍了Java数据结构之排序(头歌平台,详细注释)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

第1关:选择排序

任务描述

相关知识

代码:  

 第2关:插入排序

任务描述

相关知识

插入排序

代码:  

第3关:归并排序

任务描述

相关知识

归并排序

原理

代码:  

 第4关:快速排序

任务描述

相关知识

快速排序

代码:  

 第5关:堆排序

任务描述

相关知识

堆的性质

堆排序

用大根堆排序的基本思想

大根堆排序算法的基本操作

代码:  


第1关:选择排序

任务描述

给定一组无序的数据,如果要把它们从小到大重新排序,我们要如何实现这个排序功能呢?

本关任务:实现选择排序。

相关知识

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

Java数据结构之排序(头歌平台,详细注释),java头歌平台,数据结构,算法,排序算法

上图是一个从小到大排序的选择排序过程。第一次,我们从初始序列中找出了最小的元素11,把它放到第一位;第二次我们从剩下的元素中找出最小的元素13,把它放到第二位,以此类推,直到所有元素从小到大排好序。

代码:  
package step1;

/**
 * Created by sykus on 2018/3/20.
 */
public class SelectionSort {

    /**
     * 选择排序
     *
     * @param arr
     */
    public static void sort(int arr[]) {
        /********** Begin *********/
        int n=arr.length;//数组长度
        for(int i=0;i<n-1;i++){//从第一个数开始比较,第一位存放最小的,第二位存放第二小的,以此推类
            for(int j=i+1;j<n;j++){//查找i下标以及之后的最小值,放在i的位置
                if(arr[i]>arr[j]){//如果小就交换
                    int t=arr[i];//t存储arr[i]的值
                    arr[i]=arr[j];//arr[i]赋arr[j]的值
                    arr[j]=t;//arr[j]赋值t,即为arr[i]的值
                }
            }
            print(arr);//一个输出的方法,在下面可以看到
        }
        /********** End *********/
    }

    private static void print(int arr[]) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

}

以下是测试样例:

测试输入:2 8 7 1 3 5 6 4 预期输出:

Java数据结构之排序(头歌平台,详细注释),java头歌平台,数据结构,算法,排序算法

 第2关:插入排序

任务描述

上一关我们实现了选择排序,本关我们实现另外一种排序方法:插入排序。

本关任务:实现插入排序。

相关知识
插入排序

插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据。

假设我们输入的是5,1,4,2,3,我们从第二个数字开始,这个数字是1,我们的任务只要看看1有没有正确的位置,我们的做法是和这个数字左边的数字来比,因此我们比较1515小,所以我们就交换15,原来的排列就变成了1,5,4,2,3

接下来我们看第三个数字有没有在正确的位置。这个数字是4,它的左边数字是545小,所以我们将45交换,排列变成了1,4,5,2,3我们必须继续看4有没有在正确的位置,4的左边是114小,4就维持不动了。

再来看第四个数字,这个数字是2,我们将2和它左边的数字相比,都比2大,所以就将2一路往左移动,一直移到2的左边是1,这时候排序变成了1,2,4,5,3

最后,我们检查第五个数字,这个数字是33必须往左移,一直移到3的左边是2为止,所以我们的排列就变成了1,2,3,4,5,排序完成。

Java数据结构之排序(头歌平台,详细注释),java头歌平台,数据结构,算法,排序算法

插入排序示例

 如果难以理解,可以看作,第一次对前两个数排序,第二次对前三个数排序,第n次对第n+1个数排序,即可得插入排序的排序顺序

代码:  
package step2;

/**
 * Created by sykus on 2018/3/20.
 */
public class InsertionSort {

    public static void sort(int arr[]) {
        /********** Begin *********/
        int n=arr.length;//存储数组长度
        for(int i=1;i<n;i++){//从第二位数开始插入
            int j=i;//存储需要插入数的下标
            int t=arr[j];//存储需要插入数的值
            while(j>0 && t<arr[j-1]){//从后往前开始找比需要插入值大的值
                arr[j]=arr[j-1];//如果大就后移一位
                j--;//继续往前找
            }
            arr[j]=t;//最后将需要插入数插入j下标的位置
            print(arr);//一个输出的方法,在下面可以看到
        }
        /********** End *********/
    }

    private static void print(int arr[]) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
}

以下是测试样例:

测试输入:

  1. 6
  2. 1 5 4 3 2 6

预期输出:

Java数据结构之排序(头歌平台,详细注释),java头歌平台,数据结构,算法,排序算法

第3关:归并排序

任务描述

本关任务:实现归并排序。

相关知识
归并排序

归并排序(Merge Sort)是建立在归并操作上的一种有效的排序算法。归并是指将若干个已排序的子序列合并成一个有序的序列。若将两个有序序列合并成一个有序序列,称为二路归并。

原理

假设初始序列含有n个记录,则可看成n个有序的子序列,每个子序列长度为1。然后两两归并,得到n/2个长度为21的有序子序列;再两两归并,如此重复,直到得到一个长度为n的有序序列为止。

Java数据结构之排序(头歌平台,详细注释),java头歌平台,数据结构,算法,排序算法

Java数据结构之排序(头歌平台,详细注释),java头歌平台,数据结构,算法,排序算法

上图是一个二路归并排序过程示例,经过三次归并操作后完成了排序。

代码:  
package step3;

/**
 * Created by sykus on 2018/3/20.
 */
public class MergeSort {

    /**
     * lo, hi都是指下标
     */
    public static void sort(int arr[], int lo, int hi) {
        if (lo < hi) {
            int mid = (lo + hi) / 2;
            sort(arr, lo, mid);
            sort(arr, mid + 1, hi);
            merge(arr, lo, mid, hi);
            print(arr);
        }
    }

    private static void merge(int arr[], int p, int q, int r) {
        /********** Begin *********/
        //归并排序将两部分合并
        int n=arr.length;//存储数组长度
        int[] t=new int[n];//定义一个数组用于存储排序后的数组
        int i=p,j=q+1,k=i;;//第一部分的左边界,第二部分的左边界,t的初始下标为第一部分的左边界
        while(i<=q&&j<=r){//如果两部分都不超过他们的右边界则继续合并
            if(arr[i]<arr[j]){//比大小,小的先放入排序数组里
                t[k++]=arr[i++];//继续往后比较
            }else{//比大小,小的先放入排序数组里
                t[k++]=arr[j++];//继续往后比较
            }
        }
        //当有一个部分的越界后,另一个部分可能还没找完
        while(i<=q){//再找一遍,确保找完
            t[k++]=arr[i++];
        }
        while(j<=r){//再找一遍,确保找完
            t[k++]=arr[j++];
        }
        for(int l=p;l<=r;l++){//将排序数组的顺序返回arr数组
            arr[l]=t[l];
        }
        /********** End *********/
    }

    private static void print(int arr[]) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
}

以下是测试样例:

测试输入:

  1. 6
  2. 1 5 4 3 2 6

预期输出:

Java数据结构之排序(头歌平台,详细注释),java头歌平台,数据结构,算法,排序算法

 第4关:快速排序

任务描述

本关任务:实现快速排序。

相关知识

快速排序由C. A. R. Hoare1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

快速排序

快速排序的基本思想是: 1.先从数列中取出一个数作为基准数。 2.将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。 3.再对左右区间重复第二步,直到各区间只有一个数。

现在假设我们对6 1 2 7 9 3 4 5 10 810个数进行排序。首先在这个序列中找一个数作为基准数。为了方便,取第一个数6作为基准数。接下来,需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,类似下面这种排列: 3 1 2 5 4 6 9 7 10 8 具体过程是:从右往左找比6小的数,从左往右找6大的数,然后把这两个数交换,如下图所示,

Java数据结构之排序(头歌平台,详细注释),java头歌平台,数据结构,算法,排序算法

最后得到3 1 2 5 4 6 9 7 10 8

我们接着在对6的左右区间分别进行同样的操作。会得到类似1 2 3 5 48 7 9 10的排列。直到区间只有一个数,处理结束。

代码:  
package step4;

/**
 * Created by sykus on 2018/3/20.
 */
public class QuickSort {

    public void sort(int arr[], int low, int high) {
        /********** Begin *********/
        int i=low;//左边界,为默认主元,所以从low+1开始找,所以下面循环++i,i先加1
        int j=high+1;//右边界,high+1,所以下面循环--j,j先减1
        //主元默认为左边第一个数,arr[low]
        while(i<j){//i大于j则跳出
            while(j>low && arr[--j]>=arr[low]);//从右往左找一个比主元小的数
            while(i<high && arr[++i]<=arr[low]);//从左往右找一个比主元大的数
            if(i<j)//如果i小于j就交换
            {
            int t=arr[j];
            arr[j]=arr[i];
            arr[i]=t;
            print(arr);//每次交换都要输出
            }
            else break;//i大于j则跳出
        }
        int t=arr[j];//交换下标j与主元的位置
        arr[j]=arr[low];
        arr[low]=t;
        print(arr);//一个输出方法
        if(i>low) sort(arr,low,j-1);//如果i没越界,将右边界左移,左边界默认为主元从
        if(j<high)sort(arr,j+1,high);//如果j没越界,将左边界右移
        /********** End *********/
    }


    private static void print(int arr[]) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
}

以下是测试样例:

测试输入:

  1. 10
  2. 6 1 2 7 9 3 4 5 10 8

预期输出:

Java数据结构之排序(头歌平台,详细注释),java头歌平台,数据结构,算法,排序算法

 第5关:堆排序

任务描述

本关任务:在本关,我们将实现另一种排序算法——堆排序(heapsort)。

相关知识

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。

堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。 当一个含有n个元素的数组{k1​, k2​... ki​...kn​},当且仅当满足下列关系时称之为堆: (ki​ <= k2i​, ki​ <= k2i​+1)或者(ki​ >= k2i​, ki​ >= k2i​+1), (i = 1, 2, 3, 4... n/2)

即,如果用堆中的元素依次从上至下,从左至右构建一棵完全二叉树,那么这棵二叉树的任意节点的值都大于其子节点的值(或都小于其子结点的值),将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

堆的性质

通常堆是通过一维数组来实现的。在索引起始位置为1的情形中: 父节点i的左子节点在位置 (2i); 父节点i的右子节点在位置 (2i+1);

Java数据结构之排序(头歌平台,详细注释),java头歌平台,数据结构,算法,排序算法

大根堆堆顶元素最大

堆排序

堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得选取最大(或最小)关键字变得简单。

用大根堆排序的基本思想
  1. 先将初始数组R[1..n]构造成一个大根堆,此堆为初始的无序区。
  2. 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key
  3. 由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。
  4. 直到无序区只有一个元素为止。
大根堆排序算法的基本操作
  1. 建堆,建堆是不断调整堆的过程,从len/2处开始调整,一直到第一个节点,此处len是堆中元素的个数。
  2. 调整堆:调整堆在构建堆的过程中会用到,而且在堆排序过程中也会用到。利用的思想是比较节点i和它的孩子节点left(i),right(i),选出三者最大(或者最小)者,如果最大(小)值不是节点i而是它的一个孩子节点,那边交换节点i和该节点,然后再调用调整堆过程,这是一个递归的过程。
  3. 堆排序:堆排序是利用上面的两个过程来进行的。首先是根据元素构建堆。然后将堆的根节点取出(一般是与最后一个节点进行交换),将前面len-1个节点继续进行堆调整的过程,然后再将根节点取出,这样一直到所有节点都取出。
代码:  
package step5;

/**
 * Created by sykus on 2018/3/20.
 */
public class HeapSort {

    public static void sort(int arr[]) {
        /********** Begin *********/
        int n=arr.length;//存储数组长度
        //先将初始数组数据从上到下从左到右摆成一个完全二叉树
        for(int i=n/2-1;i>=0;i--){//从n/2-1的下标开始
            BuildPile(arr,i,n);//导入数组以及当前需要调整的数的下标,数组长度
        }
        for(int i=n-1;i>0;i--){
            int t=arr[0];//将第一个数即最大值与最后一个没被排好的数交换
            arr[0]=arr[i];
            arr[i]=t;
            BuildPile(arr,0,i);//从0~i重新建堆
            print(arr);//一个输出方法,下面可以看见
        }
    }
    //需要自己写一个递归方法
public static void BuildPile(int[] arr,int f,int n){
        int max=f;//存储最大值的下标
        int lc=2*f+1;//左子树下标
        int rc=2*f+2;//右子树下标
        if(lc<n && arr[lc]>arr[max]){//如果下标没有超过数组表示存在,比较大小
            max=lc;//如果大就存储
        }
        if(rc<n && arr[rc]>arr[max]){//如果下标没有超过数组表示存在,比较大小
            max=rc;//如果大就存储
        }
        if(f==max)//如果最大值是本身则返回
        {
            return;
        }
        //否则交换,他们的值
            int t=arr[f];
            arr[f]=arr[max];
            arr[max]=t;
            f=max;//查找max值的左右子树
            BuildPile(arr,f,n);
    }
        /********** End *********/
    private static void print(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

}

以下是测试样例:

测试输入:

  1. 8
  2. 2 8 7 1 3 5 6 4

预期输出:

Java数据结构之排序(头歌平台,详细注释),java头歌平台,数据结构,算法,排序算法文章来源地址https://www.toymoban.com/news/detail-804126.html

到了这里,关于Java数据结构之排序(头歌平台,详细注释)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构---排序】很详细的哦

    本篇文章介绍数据结构中的几种排序哦~ 文章目录 前言 一、排序是什么? 二、排序的分类 1.直接插入排序 2.希尔排序 3.选择排序 4.冒泡排序 5.快速排序 6.归并排序 总结   排序在我们的生活当中无处不在,当然,它在计算机程序当中也是一种很重要的操作,排序的主要目的是

    2024年02月08日
    浏览(36)
  • 数据结构进阶篇 之【选择排序】详细讲解(选择排序,堆排序)

    民以食为天,我以乐为先 嘴上来的嘘寒问暖,不如直接打笔巨款 1.1 基本思想 1.2 实现原理 1.3 代码实现 1.4 直接选择排序的特性总结 跳转链接:数据结构 之 堆的应用 –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀

    2024年04月09日
    浏览(42)
  • 《数据结构》八大排序(详细图文分析讲解)

    目录 排序 排序的应用       排序简介 排序的分类 排序算法的好坏评判 冒泡排序法  思路分析 代码实现   选择排序法 思路分析 代码实现   插入排序 思路分析 代码实现  希尔排序 思路分析 代码演示  归并排序法  思路分析 代码演示  快速排序  思路分析 代码实现 

    2024年02月03日
    浏览(48)
  • 数据结构进阶篇 之 【插入排序】详细讲解(直接插入排序,希尔排序)

    千万不要因为一件事不会做而失去信心,你又不是只有这一件事不会,你还有很多呢 1.1 基本思想 1.2 实现原理 1.3 代码实现 1.4 直接插入排序的特性总结 2.1 基本思想 2.2 实现原理 2.3 代码实现 2.4希尔排序的特性总结 –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–

    2024年04月12日
    浏览(73)
  • 【数据结构】插入排序详细图解(一看就懂)

      💯 博客内容:【数据结构】插入排序详细图解(一看就懂) 😀 作  者:陈大大陈 🦉所属专栏:数据结构笔记 🚀 个人简介:一个正在努力学技术的准前端,专注基础和实战分享 ,欢迎私信! 💖 欢迎大家:这里是CSDN,我总结知识和写笔记的地方,喜欢的话请三连,

    2024年02月07日
    浏览(50)
  • 数据结构:一篇拿捏十大排序(超详细版)

    排序: 所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 稳定性: 假定在待排序的记录序列中,存在多个具有相同的的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前, 而

    2024年02月08日
    浏览(52)
  • 数据结构进阶篇 之 【交换排序】(冒泡排序,快速排序递归、非递归实现)详细讲解

    当你觉的自己不行时,你就走到斑马线上,这样你就会成为一个行人 1.1 基本思想 1.2 实现原理 1.3 代码实现 1.4 冒泡排序的特性总结 2.1 基本思想 2.2 递归实现 2.2.1 hoare版 2.2.2 前后指针版本 2.3 快速排序优化 2.3.1 随机数选key 2.3.2 三数取中选key 2.3.3 递归到小的子区间使用插入排

    2024年04月10日
    浏览(67)
  • 【数据结构——9大基础排序】一文掌握九大经典排序(配有详细图文说明!!!)

    算法基本思想:(从大到小排序) 在一个 非递减 的有序数组中,要新增一个元素 x ,有两个方法: 1.从数组的头部开始向后遍历,寻找 第一个比x 大 的元素 y ,从y元素开始的所有元素全部向后移动,最后将x元素插入数组。(×) 2.从数组的尾部开始向后向前遍历,寻找 第

    2024年02月08日
    浏览(45)
  • 数据结构排序——详细讲解归并排序(c语言实现递归及非递归)

    上次是快排和冒泡:数据结构排序——详解快排及其优化和冒泡排序(c语言实现、附有图片与动图示意) 今天为大家带来归并排序 归并排序是一种分治算法,它将序列分成两个子序列,分别对 子序列进行排序 ,然后将排序好的子序列 合并起来 。这个过程可以 递归 地进行,

    2024年01月22日
    浏览(66)
  • [数据结构 -- 手撕排序第二篇] 一篇带你详细了解希尔排序

    目录 1、常见排序算法 1.1 插入排序基本思想 2、希尔排序 2.1 希尔排序( 缩小增量排序 ) 2.1.1 预排序阶段 2.1.2 插入排序阶段 2.2 单趟希尔排序 2.2.1 思路分析 2.2.2 代码实现 3、希尔排序代码实现 4、希尔排序时间复杂度 5、希尔排序与插入排序效率对比 6、希尔排序特性总结 直接

    2024年02月13日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包