目录

  • 一、基本概念
    • (1)算法的稳定性
    • (2)排序的分类
    • (3)算法的性能
  • 二、插入排序
    • (1)直接插入排序 / InsertSort
    • (2)折半插入排序
    • (3)希尔排序 / 缩小增量排序 / Shell's Sort
  • 三、交换排序
    • (1)冒泡排序 / 起泡排序 / Bubble Sort
    • (2)快速排序 / QuickSort
  • 四、选择排序
    • (1)简单选择排序 / SelectSort
    • (2)堆排序 / Heap Sort
  • 五、归并排序 / MergeSort
  • 六、基数排序
  • 七、各种内部排序算法的比较

一、基本概念

(1)算法的稳定性

(2)排序的分类

(3)算法的性能

内部排序算法的性能取决于算法的时间复杂度和空间复杂度,而时间复杂度一般是由比较和移动的次数决定的。

二、插入排序

插入排序的基本操作是在一个有序表中进行查找和插入。

(1)直接插入排序 / InsertSort

基本操作:将一个记录插入到已排好序的有序表中。从而得到一个新的、记录数增1的有序表。

基本思想:假设在排序过程中,待排序表L[1…n]在某次排序过程中的某一时刻状态如下:

要将元素L(i)插入到已有序的子序列L[ 1…i-1 ],需要执行以下操作,其中L[ ]表示一个表,L()表示一个元素:
 
1)查找出L(i)在L [ 1 … i - 1 ]中插入位置k。
 
2)将L [ k … i - 1 ]中的所有元素依次后移一个位置。
 
3)将L(i)复制到L(k)。
 
为了实现对L[1 … n]的排序,可以将L(2)~L(n)依次插入前面已排好序的子列表
 
初始L[ 1 ]视为一个已经排好序的子序列。

示例

代码实现

public class InsertSort {//输出数组中的元素public static void print(int[] arr) {       //这里一定要是staticSystem.out.print("将数组中的元素从小到大进行排序:");for (int i = 0;i < arr.length;i++)System.out.print(arr[i] + "   ");}//对数组中的元素进行 直接插入排序public static void sort(int[] arr) {    //这里一定要是staticif (arr.length >= 2) {              //数组长度为1时,没有必要进行排序//不采用哨兵,数组中元素从0位置开始存放,如果采用哨兵,数组中元素从1位置开始存放,则arr[0]为哨兵for (int i = 1; i < arr.length; i++) {      //从数组的第二个元素开始处理int x = arr[i];         //用x存放现在处理的数据,以便后面进行数据的插入操作。int j = i -1 ;for (;j >= 0 && arr[j] > x;j --)   //将待处理的元素与这一元素前面的元素进行比较,这里循环中的x不可以写成arr[i],因为此时arr[i]上的元素可能已经变化,不是原来的值arr[j + 1] = arr[j];                //进行数据的移动操作arr[j + 1] = x;         //将处理的这个元素插入到合适的位置}}}//测试public static void main(String[] args) {int[] a = {3,1,5,7,2,8,4,9,6};sort(a);print(a);}
}

运行结果

(2)折半插入排序

查找操作可使用"折半查找"。

(3)希尔排序 / 缩小增量排序 / Shell’s Sort

基本思想:先将整个待排 记录序列 分割成若干子序列 分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行一次直接插入排序。

示例

特点:子序列的构成不是简单地"逐段分割",而是将相隔某个"增量"地记录组成一个子序列。

三、交换排序

(1)冒泡排序 / 起泡排序 / Bubble Sort

基本思想

示例

代码实现

public class BubbleSort {//输出数组中的元素public static void print(int[] arr) {       //这里一定要是staticSystem.out.print("将数组中的元素从小到大进行排序:");for (int i = 0;i < arr.length;i++)System.out.print(arr[i] + "   ");}public static void sort(int[] arr) {for (int i = 0;i < arr.length - 1 ;i ++) {boolean flag = false;   //表示本趟冒泡是否发生交换的标志for (int j = arr.length - 1 ;j > i ;j --)   //一趟冒泡过程if (arr [j - 1] > arr [j]) {            //若为逆序//swap (arr[j-1],arr[j]) 交换int temp = arr[j];arr[j] = arr[j - 1];arr[j - 1] = temp;flag = true;}if (flag == false)      //本趟遍历后没有发生交换,说明表已经有序break;  //或者return;}}//测试public static void main(String[] args) {int[] a = {3,1,5,7,2,8,4,9,6};sort(a);print(a);}
}

运行结果

(2)快速排序 / QuickSort

是对冒泡排序地改进。

基本思想:通过一趟排序将 待排记录 分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

示例

代码实现

public class QuickSort {//输出数组中的元素public static void print(int[] arr) {       //这里一定要是staticSystem.out.print("将数组中的元素从小到大进行排序:");for (int i = 0;i < arr.length;i++)System.out.print(arr[i] + "   ");}public static void sort(int[] arr,int low,int high) {if (low < high){        //递归跳出的条件int pivotpos = Partition(arr,low,high);     //划分sort(arr,low,pivotpos - 1);sort(arr,pivotpos + 1 ,high);}}//划分元素操作,将表arr[low...high]划分为满足上述条件的两个子表public static int Partition(int[] arr,int low,int high) {  //一趟划分int pivot = arr[low];   //设当前表中第一个元素为枢轴,对表进行划分while(low < high) {       //循环跳出条件while (low < high && arr[high] >= pivot)   --high;arr[low] = arr[high];   //将比枢轴小的元素移动到左端while (low < high && arr[low] <= pivot)   ++low;arr[high] = arr[low];   //将比枢轴大的元素移动到右端}//whilearr[low] = pivot;   //枢轴元素存放到最终位置return low;     //返回存放枢轴的最终位置}//测试public static void main(String[] args) {int[] a = {3,1,5,7,2,8,4,9,6};sort(a,0,a.length - 1);print(a);}
}

运行结果

四、选择排序

基本思想:每一趟在 n-i+1 (i = 1,2,…,n-1)个记录中选取关键字最小的记录作为有序序列中第 i 个记录。

(1)简单选择排序 / SelectSort

基本操作:首先在未排序数列中找到最小元素,然后将其与数列的首部元素进行交换,然后,在剩余未排序元素中继续找出最小元素,将其与已排序数列的末尾位置元素交换。以此类推,直至所有元素圴排序完毕.
 
第 i 趟简单选择排序的操作为:通过 n-i 次关键字间的 比较,从 n-i+1 个记录中选出关键字最小的记录,并和第 i (1 ≤ i ≤ n)个记录交换。
 
假设排序表为L [ 1…n ],第 i 趟排序即从L[ i … n ]中选择关键字最小的元素与L(i)交换,每一趟排序可以确定一个元素的最终位置,这样经过 n - 1 趟排序就可使得整个排序表有序。

代码实现

public class SelectSort {//输出数组中的元素public static void print(int[] arr) {       //这里一定要是staticSystem.out.print("将数组中的元素从小到大进行排序:");for (int i = 0;i < arr.length;i++)System.out.print(arr[i] + "   ");}public static void sort(int[] arr) {for (int i = 0; i < arr.length - 1 ;i ++){  //一共进行 n - 1 趟int min = i;                            //记录最小元素位置for (int j = i + 1 ;j < arr.length;j ++)    //在arr[i...n-1]中选择最小的元素if (arr[j] < arr[min])min = j;                    //更新最小元素位置if (min != i) {//swap (arr[i],arr[min]) 交换int temp = arr[i];arr[i] = arr[min];arr[min] = temp;}}}//测试public static void main(String[] args) {int[] a = {3,1,5,7,2,8,4,9,6};sort(a);print(a);}
}

运行结果

(2)堆排序 / Heap Sort

堆排序需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。

五、归并排序 / MergeSort

"归并"的含义是将两个或两个以上的有序表组合成一个新的有序表。

示例:2路归并排序(两两归并)

代码实现

public class MergeSort {//输出数组中的元素public static void print(int[] arr) {       //这里一定要是staticSystem.out.print("将数组中的元素从小到大进行排序:");for (int i = 0;i < arr.length;i++)System.out.print(arr[i] + "   ");}public static void sort(int[] arr,int low,int high) {if (low < high){        //递归跳出的条件int mid = (low + high) / 2; //从中间划分两个子序列sort(arr,low,mid);          //对左侧子序列进行递归排序sort(arr,mid+1,high);   //对右侧子序列进行递归排序Merge(arr,low,mid,high);    //归并}}//Merge()的功能是将前后相邻的两个有序表归并为一个有序表。//设两段有序表arr[low...mid]、arr[mid+1...high]存放在同一顺序表中的相邻位置,先将它们复制到辅助数组temp中。//每次从对应temp数组中的两个段取出一个记录进行关键字比较,将较小者放入arr中,//当辅助数组temp中有一段的下标超出其对应的表长(即该段的所有元素都已经复制到数组arr中)时,将另一段中的剩余部分直接复制到arr数组中。public static void Merge(int[] arr,int low,int mid,int high) {//表arr的两段A[low...mid]和arr[mid+1...high]各自有序,将它们合并成一个有序表//Java中没有malloc对内存进行直接操作的函数,直接使用new来申请。int[] temp = new int[arr.length+1];     //创建一个辅助数组tempint i,j,k;for (k = low;k <= high; k ++)temp[k] = arr[k];   ///将arr中所有元素复制到temp中for (i =low,j = mid + 1,k = i;i <= mid && j <= high ;k ++) {if (temp[i] <= temp[j])    //比较temp的左右两段中的元素arr[k] = temp[i++];     //将较小值复制到arr数组中elsearr[k] = temp[j++];}//for//下面的两个while循环只有1个会执行while (i <= mid)arr[k++] = temp[i ++];      //若第一个表未检测完,复制while (j <= high)arr[k++] = temp[j++];       //若第二个表未检测完,复制}//测试public static void main(String[] args) {int[] a = {3,1,5,7,2,8,4,9,6};sort(a,0,a.length - 1);print(a);}
}

运行结果:

六、基数排序

前面所讲述的排序主要是通过关键字间的比较和移动记录两种操作。
 
通过比较两个关键字的大小,确定对应元素的前后关系,然后通过移动元素以达到有序。
 
基数排序不需要进行 记录关键字 间的比较。
 
基数排序是一种借助多关键字排序的思想对单逻辑关键字进行排序的方法。

示例

七、各种内部排序算法的比较


参考:《数据结构:C语言版》(严蔚敏)清华大学出版社、王道2022年数据结构考研复习指导

Java--排序算法相关推荐

  1. Java排序算法:冒泡排序

    Java排序算法:冒泡排序 //创建数组并赋值int[] data = new int[] {11,10,55,78,100,111,45,56,79,90,345,1000};for(int i=0 ...

  2. Java十大排序算法总结,Java排序算法总结之冒泡排序

    本文实例讲述了Java排序算法总结之冒泡排序.分享给大家供大家参考.具体分析如下: 前言:冒泡排序(BubbleSort)就是依次比较相邻的两个数,将小数放在前面,大数放在后面. 下面让我们一起    ...

  3. Java排序算法之直接选择排序

    Java排序算法之直接选择排序 基本过程:假设一序列为R[0]~R[n-1],第一次用R[0]和R[1]~R[n-1]相比较,若小于R[0],则交换至R[0]位置上.第二次从R[1]~R[n-1]中选 ...

  4. java排序算法 sort_Java排序算法之SleepSort排序示例

    本文实例讲述了Java排序算法之SleepSort排序.分享给大家供大家参考,具体如下: 分享一个很有创意的排序算法:sleepSort .巧妙利用了线程的sleep(),代码如下: public c ...

  5. java 排序算法总结,Java排序算法总结之归并排序

    本文实例讲述了Java排序算法总结之归并排序.分享给大家供大家参考.具体分析如下: 归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作.和快速排序类似,让我们一起来看 ...

  6. Java排序算法——插入排序(Insertion Sort)

    之前总结了交换排序的冒泡排序与选择排序的简单选择排序,这次我们来看看插入排序的简单插入排序~ 往期传送门: 冒泡排序: Java排序算法--冒泡排序(Bubble Sort)https://blog. ...

  7. Java排序算法——选择排序

    Java排序算法--选择排序(Selection sort) 传送门 冒泡排序 插入排序 简述 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理如下.首先在未排序序列中找 ...

  8. java排序算法(插入排序,冒泡排序,选择排序)

    java排序算法(插入排序,冒泡排序,选择排序) 先了解原理,然后自己跟着敲一下,加深印象 CMD编译命令:javac -encoding utf-8 SortList.java && ...

  9. java 排序算法 讲解_java实现排序算法之冒泡排序法详细讲解

    冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交 ...

  10. Java排序算法总结

    稳定排序: * 泡沫排序(bubble sort) - O(n²) * 插入排序 (insertion sort)- O(n²) * 桶排序 (bucket sort)- O(n); 需要 O(k)  ...

最新文章

  1. 视觉SLAM直接法与特征法及其在多传感融合中的思考
  2. 《小印记》源码分享--极光推送服务器篇
  3. wlop一张多少钱_50etf期权交易一张合约多少钱?
  4. Windows 8常用快捷键
  5. Python 学习编程 【for语句breakcontinue语句使用】(一)
  6. vue 跨域:使用vue-cli 配置 proxyTable 实现跨域问题
  7. 电商大促首焦背景素材|大火C4D元素
  8. python 编译成exe黑屏_python''外星人入侵''打包成exe遇到的问题和解决办法,闪退,黑屏。...
  9. idea使用svn拉取项目代码_使用 IDEA 搭建 Hadoop3.1.1 项目
  10. [VB]多级目录创建函数,支持很深的目录创建。
  11. 数据分析人的职场天花板
  12. Nginx: 解决connect() to xxxx failed (13: Permission denied) while connecting to upstream的问题
  13. RJ45接口定义及网线线序
  14. RQNOJ 30 愚蠢的矿工 解题报告
  15. 游戏开发常遇到数据一致性BUG,怎么解?
  16. 求两者较大值的max函数的用法(c++基础)
  17. Linus Torvalds:最庆幸的是 30 年后,Linux 不是一个“死”项目
  18. 最简单DIY基于C#和51单片机上下位机一体化的PCA9685舵机控制程序
  19. 海康集成报警主机等设备
  20. 厦门大学“网宿杯“17届程序设计竞赛决赛(同步赛) #题解 #题目都超有趣呀

热门文章

  1. Windows10常用Windows自检方法
  2. 电脑计算机怎么显示到桌面,怎么显示我的电脑到桌面
  3. 1212 无向图最小生成树
  4. Reaseach,Refresh和reRead的区别
  5. Linux-nali解析IP归属信息
  6. 【统计学】分类数据分析 相关分析 方差分析 比较 研究思路 spss
  7. 不同计算机打印机共享,不同系统之间设置打印机共享
  8. python 区块链_如何用Python快速实现区块链?
  9. Python selenium 加载并保存QQ群成员,去除其群主、管理员信息的示例代码
  10. 中职计算机应用基础表格制作说课稿,表格制作说课稿.doc