选择排序

思想

n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果:
①初始状态:无序区为R[1..n],有序区为空。
②第1趟排序
在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。
……
③第i趟排序

第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R(i..n)。该趟排序从当前无序区中选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。

排序实例

初始关键字 [49 38 65 97 76 13 27 49]
第一趟排序后 13 [38 65 97 76 49 27 49]
第二趟排序后 13 27 [65 97 76 49 38 49]
第三趟排序后 13 27 38 [97 76 49 65 49]
第四趟排序后 13 27 38 49 [76 97 65 49 ]
第五趟排序后 13 27 38 49 49 [97 65 76]
第六趟排序后 13 27 38 49 49 65 [97 76]
第七趟排序后 13 27 38 49 49 65 76 [97]
最后排序结果 13 27 38 49 49 65 76 97

Java实现代码如下:

package selectsort;public class Sort {public static void main(String[] args){int[] a = {8,77,66,99,2,7,4,6,100,34};int[] b ; b = selectsort(a);for(int i  = 0; i < b.length; i++){System.out.println(b[i]);}}public static int[] selectsort(int[] p){int temp = 0;int minindex = 0;int[] array = p.clone();for(int i = 0; i < array.length; i++){minindex = i;for(int j = i+1; j < array.length; j++){if(array[minindex] > array[j] )minindex = j;}temp = array[i];array[i] = array[minindex];array[minindex] = temp;}return array;}
}

结果验证正确。

冒泡法

原理

冒泡排序算法的运作如下:
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
算法分析

算法稳定性

冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

Java实现代码:

package bubblesort;public class Bubblesort {public static void main(String[] args){int[] a = {8,77,66,99,2,7,4,6,100,34};int[] b;b = bubble(a);for(int i =0; i <b.length; i++ ){System.out.println(b[i]);}}public static int[] bubble(int[] a){int[] array = a.clone();for(int i  = 0; i < array.length - 1; i++){for(int j = 0; j < array.length - 1 - i; j++){if(array[j] > array[j+1])sway(array,j,j+1);}}return array;}public static void sway(int[] b, int m, int n){int temp = b[m];b[m] = b[n];b[n] = temp;}}

插入排序

插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

算法描述一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:从第一个元素开始,该元素可以认为已经被排序取出下一个元素,在已经排序的元素序列中从后向前扫描如果该元素(已排序)大于新元素,将该元素移到下一位置重复步骤3,直到找到已排序的元素小于或者等于新元素的位置将新元素插入到该位置后重复步骤2~5如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的一个变种,称为二分查找排序。

Java示例代码如下:

 

package insertsort;public class Insert {public static void main(String[] args){int[] a = {500,77,66,99,2,7,4,6,100,34};int[] b;b = insert(a);for(int i =0; i <b.length; i++ ){System.out.println(b[i]);}}public static int[] insert(int[] c){int[] array = c.clone();for(int i  = 1; i < array.length; i++){if(array[i] < array[i - 1]){int temp = array[i];int j  = i;while((j>0)&&(array[j - 1] > temp)){array[j] = array[j - 1];j--;}array[j] = temp; }}return array;}
}

希尔排序

希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。
假设有一个很小的数据在一个已按升序排好序的数组的末端。如果用复杂度为O(n2)的排序(冒泡排序或插入排序),可能会进行n次的比较和交换才能将该数据移至正确位置。而希尔排序会用较大的步长移动数据,所以小数据只需进行少数比较和交换即可到正确位置。
一个更好理解的希尔排序实现:将数组列在一个表中并对列排序(用插入排序)。重复这过程,不过每次用更长的列来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身仅仅对原数组进行排序(通过增加索引的步长,例如是用i += step_size而不是i++)。
例如,假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:
13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10
然后我们对每列进行排序:
10 14 73 25 23
13 27 94 33 39
25 59 94 65 82
45
将上述四行数字,依序接在一起时我们得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ].这时10已经移至正确位置了,然后再以3为步长进行排序:
10 14 73
25 23 13
27 94 33
39 25 59
94 65 82
45
排序之后变为:
10 14 13
25 23 33
27 25 59
39 65 73
45 94 82
94
最后以1步长进行排序(此时就是简单的插入排序了)。

package shellsort;public class shellsort {public static void main(String[] args){int[] a = {500,77,66,99,2,7,4,6,100,34};int[] b;b = shell(a);for(int i =0; i <b.length; i++ ){System.out.println(b[i]);}}public static int[] shell(int[] a){int[] array = a.clone();int len = array.length;int i = 0;int j = 0;int k = -1;int temp = -1;int gap = len;do{gap = gap / 3 + 1; for(i=gap; i<len; i+=gap){k = i;temp = array[k];for(j=i-gap; (j>=0) && (array[j]>temp); j-=gap){array[j+gap] = array[j];k = j;}array[k] = temp;}}while( gap > 1 );return array;}
}

快速排序

思想:从待排序记录序列中选取一个记录(通常选取第一个记录)为枢轴其关键字设为k1,然后将其余关键字小于k1的记录移到前面去,而将关键字大于k1的记录移到后面,结果将待排序序列分成了两个子表最后将关键字为k1的记录查到其分界线的位置处.
算法步骤:假设待划分序列为r[left],r[left+1],.......r[right],具体实现上述划分过程时,可以设两个指针i和j,他们的初值分别为left,right.首先将基准记录r[left]移至变量x中,是r[left],即r[i]相当于空单元,然后反复进行如下两个扫描过程,直到i和j相遇
(1)j从右向左扫描,直到r[j].key<x.key时,将r[j]移至控单元r[i],此时r[j]相当于控单元。
(2)i从左向后扫描,直到r[i].key>x.key时,将r[i]移至空单元r[j],此时r[i]相当于空单元。
当i和j相遇时,r[i](或r[j])相当与空单元,且r[i]左边所有记录的关键字均不大于基准记录的关键字,而r[i]右边所有记录的关键字均不小于基准记录的关键字,最后将基准记录移至r[i]中,就完成了一次划分过程。最后对子表进行递归调用排序函数进行排序。
Java示例代码如下:
package quicksort;public class Quick {public static void main(String[] args){int[] a = {500,77,66,99,2,7,4,6,100,34,1000,888,777,666,555,333,222,111,87,45,69,12,45,};QuickSort(a,a.length);for(int i =0; i <a.length; i++ ){System.out.println(a[i]);}}public static void swap(int[] array, int i, int j){int temp = array[i];array[i] = array[j];array[j] = temp;}public static int partition(int[] array, int low, int high){int pv = array[low];while( low < high ){while( (low < high) && (array[high] >= pv) ){high--;}swap(array, low, high);while( (low < high) && (array[low] <= pv) ){low++;}swap(array, low, high);}return low;}public static void QSort(int[] array, int low, int high){if( low < high ){int pivot = partition(array, low, high);QSort(array, low, pivot-1);QSort(array, pivot+1, high);}}public static void QuickSort(int[] array, int len) // O(n*logn){QSort(array, 0, len-1);}}

归并排序
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。值得注意的是归并排序是一种稳定的排序方法。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
归并操作
归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。
如 设有数列{6,202,100,301,38,8,1}
初始状态:6,202,100,301,38,8,1
第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;
第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;
第三次归并后:{1,6,8,38,100,202,301},比较次数:4;
总的比较次数为:3+4+4=11,;
逆序数为14;
算法描述
归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾

Java示例代码如下:
package MergeSortClass;public class MergeSortClass {private int[] SortOut;public void printSortedOutput() {for (int i = 0; i < this.SortOut.length; i++) {System.out.print(this.SortOut[i] + " ");}}public static void main(String[] args) {int[] in = { 2, 5, 3, 8, 6, 7, 1, 4, 0, 9 };MergeSortClass msTest = new MergeSortClass(in);msTest.printSortedOutput();}public MergeSortClass(int[] in){this.SortOut=this.MergeSort(in);}private int[] MergeSort(int[] i_list){if (i_list.length == 1) {return i_list;} else {int[] listL = new int[i_list.length / 2];int[] listR = new int[i_list.length - i_list.length / 2];int Center = i_list.length / 2;for (int i = 0; i < Center; i++) {listL[i] = i_list[i];}for (int i = Center, j = 0; i < i_list.length; i++, j++) {listR[j] = i_list[i];}int[] SortedListL=MergeSort(listL);int[] SortedListR=MergeSort(listR);int[] o_list = MergeTwoList(SortedListL, SortedListR);return o_list;}}private int[] MergeTwoList(int[] listL, int[] listR) {int i = 0, j = 0;int[] o_list = new int[listL.length + listR.length];int foot = 0;while (i < listL.length && j < listR.length) {if (listL[i] <= listR[j]) {o_list[foot] = listL[i];i++;} else {o_list[foot] = listR[j];j++;}foot++;}if (i == listL.length) {while (j < listR.length) {o_list[foot++] = listR[j++];}} else { // j==listR.lengthwhile (i < listL.length) {o_list[foot++] = listL[i++];}}return o_list;}
}

转载于:https://www.cnblogs.com/riasky/p/3455594.html

几种经典的数据排序及其Java实现相关推荐

  1. std中稳定排序算法_源代码库已开放 | 哈工大硕士生用 Python 实现了 11 种经典数据降维算法...

    转自:AI开发者 网上关于各种降维算法的资料参差不齐,同时大部分不提供源代码.这里有个 GitHub 项目整理了使用 Python 实现了 11 种经典的数据抽取(数据降维)算法,包括:PCA.LDA ...

  2. 文本处理算法_基于 Python 的 11 种经典数据降维算法

    网上关于各种降维算法的资料参差不齐,同时大部分不提供源代码.这里有个 GitHub 项目整理了使用 Python 实现了 11 种经典的数据抽取(数据降维)算法,包括:PCA.LDA.MDS.LLE. ...

  3. python用tsne降维_哈工大硕士实现了 11 种经典数据降维算法,源代码库已开放

    网上关于各种降维算法的资料参差不齐,同时大部分不提供源代码.这里有个 GitHub 项目整理了使用 Python 实现了 11 种经典的数据抽取(数据降维)算法,包括:PCA.LDA.MDS.LLE. ...

  4. python 最优化算法库_哈工大硕士生用?Python 实现了 11 种经典数据降维算法,源代码库已开放...

    雷锋网 AI 开发者按:网上关于各种降维算法的资料参差不齐,同时大部分不提供源代码.这里有个 GitHub 项目整理了使用 Python 实现了 11 种经典的数据抽取(数据降维)算法,包括:PCA. ...

  5. 基于 Python 的 11 种经典数据降维算法

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 网上关于各种降维算法的资料参差不齐,同时大部分不提供源代码.这里有 ...

  6. java实现apriori算法_七大经典、常用排序算法的原理、Java 实现以及算法分析

    0. 前言 大家好,我是多选参数的程序员,一个正再 neng 操作系统.学数据结构和算法以及 Java 的硬核菜鸡.数据结构和算法是我准备新开的坑,主要是因为自己再这块确实很弱,需要大补(残废了一般) ...

  7. 23种经典设计模式都有哪些,如何分类?Java设计模式相关面试

    23种经典设计模式都有哪些,如何分类? 23种经典设计模式都有哪些,如何分类? java常用的设计模式?说明工厂模式 Java 中的23 种设计模式: Factory(工厂模式), Builder(建 ...

  8. 使用qsort对不连续的内存数据排序_一点就懂的十大经典排序算法

    我是CSDN博主「雨夜※繁华」,这是我的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明. 原文链接:一点就懂的经典十大排序算法_大数据_LH is programmin ...

  9. 3分钟快速实现:9种经典排序算法的可视化

    作者 | 爱笑的眼睛 来源 | 恋习Python(ID:sldata2017) 最近在某网站上看到一个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感. ▼ 6分钟演示15种排序算法 不知道 ...

最新文章

  1. axr_Lab1_scan_top_down_flow(下)
  2. JavaMail发送和接收邮件
  3. codevs 1043 方格取数 2000年NOIP全国联赛提高组
  4. 机器学习对价格预测做模型与应用
  5. 《计算机科学与工程导论:基于IoT和机器人的可视化编程实践方法第2版》一1.1 计算机科学和工程的课程体系及职业发展...
  6. [五]java函数式编程归约reduce概念原理 stream reduce方法详解 reduce三个参数的reduce方法如何使用...
  7. wdr5600 虚拟服务器,TP-Link WDR5600路由器端口映射设置教程
  8. Echarts数据可视化series-effectscatter特效散点图,开发全解+完美注释
  9. springmvc工作流程_springMVC工作原理及流程详细讲解
  10. 如何查询硬盘序列号,百度的答案全是错的
  11. 北京内推 | 华为诺亚方舟实验室招聘计算机视觉研究实习生
  12. stm32 matlab 滤波器,STM32实现IIR滤波器,可用matlab生成的头文件
  13. sap生产工单报工_SAP报工PP用户操作手册——生产订单确认CO11N V100512.doc
  14. mysql命令执行cmd命令_mysql cmd常用命令
  15. ubuntu安装github 3D渲染库dirt
  16. 电脑W ndoWs未能启动怎么办,Win7系统电脑开机显示“Windows未能启动”的解决方法...
  17. svg基础+微信公众号交互(一)
  18. 加元预测:油价仍是关键驱动因素 - 加元/日元、美元/加元设置
  19. 特斯拉电动汽车售价将平均上调3% 不包括3.5万美元版Model 3
  20. is not marked as executable. If this was downloaded or copied form an untrusted source

热门文章

  1. 视觉slam十四讲ch6曲线拟合 代码注释(笔记版)
  2. Google Mesa概览
  3. SetProcessWorkingSetSize 函数的骗局
  4. Android基础教程(三)之------ Activity 窗口切换
  5. 利用Apache POI读取并解析Excel的数据
  6. 【vscode】编译java时报错乱码
  7. PHP 实现二分查找
  8. 安全市场五巨头将面临新兴厂商的挑战
  9. 第八章 Python 对象和类
  10. Linux中使用crontab命令启用自定义定时任务