1、冒泡排序

冒泡排序是排序算法中最基本的一种排序方法,该方法逐次比较两个相邻数据的大小并交换位置来完成对数据排序,每次比较的结果都找出了这次比较中数据的最大项,因为是逐次比较,所以效率是O(N^2)的。

  1. public void bubbleSort() {
  2. int out,in;
  3. for(out=index-1; out>1; --out) {
  4. for(in=0; in<out; ++in) {
  5. if(array[in]>array[in+1]) {
  6. swap(in, in+1);
  7. }
  8. }
  9. }
  10. }
  11. public void swap(int dex1, int dex2) {
  12. int temp = array[dex1];
  13. array[dex1] = array[dex2];
  14. array[dex2] = temp;
  15. }
public void bubbleSort() {
int out,in;
for(out=index-1; out>1; --out) {
for(in=0; in<out; ++in) {
if(array[in]>array[in+1]) {
swap(in, in+1);
}
}
}
} public void swap(int dex1, int dex2) {
int temp = array[dex1];
array[dex1] = array[dex2];
array[dex2] = temp;
}

2、选择排序

选择排序对冒泡排序进行了优化,在每次遍历比较的过程中不进行交换,而是记录本次遍历的最小值,在遍历结束后再将最小值移到这次遍历的开始位置。这样虽然比较次数没有改变,但交换的次数大大减少,一共只需要N次交换。因为比较的次数没变,所以效率任然是O(N^2)的。

  1. public void selectionSort() {
  2. int out, in;
  3. for(out=0; out<index-1; ++out) {
  4. int temp = out;
  5. for(in=out+1; in<index; ++in) {
  6. if(array[in] < array[temp]) {
  7. temp = in;
  8. }
  9. }
  10. swap(out, temp);
  11. }
  12. }
public void selectionSort() {
int out, in;
for(out=0; out<index-1; ++out) {
int temp = out;
for(in=out+1; in<index; ++in) {
if(array[in] < array[temp]) {
temp = in;
}
}
swap(out, temp);
}
}

3、插入排序

插入排序充分利用已排列好的数据,然后将未排序的数据插入到已排数据的队伍当中,这样每插入一个未排序数据已排队伍都将增加一个成员,最终达到排序的目的。

  1. public void insertionSort() {
  2. int out ,in;
  3. for(out=1; out<index; ++out) {
  4. int temp = array[out];
  5. in = out;
  6. while(in>0 && temp<array[in-1]) {
  7. array[in] = array[in-1];
  8. --in;
  9. }
  10. array[in] = temp;
  11. }
  12. }
public void insertionSort() {
int out ,in;
for(out=1; out<index; ++out) {
int temp = array[out];
in = out;
while(in>0 && temp<array[in-1]) {
array[in] = array[in-1];
--in;
}
array[in] = temp;
}
}

4、归并排序

归并排序是将两个有序数组合并为一个有序数组的排序,应用在一般排序上要结合二分法递归地将数组依次归并,最终得到一个大的有序数组。归并的效率是O(NlogN)的,但要额外开辟一个数组来存放临时数据,所以占用空间要大一倍。

  1. public void mergeSort() {
  2. int[] newArray = new int[index];
  3. recMergeSort(newArray, 0, index-1);
  4. }
  5. private void recMergeSort(int[] data, int low, int upper) {
  6. if(low == upper) {
  7. return;
  8. }
  9. int mid = (low + upper)/2;
  10. recMergeSort(data, mid+1, upper);
  11. recMergeSort(data, low, mid);
  12. merge(data, low, mid+1, upper);
  13. }
  14. private void merge(int[] data, int lowStart, int highStart, int upperBound) {
  15. int j = 0;
  16. int lowBound = lowStart;
  17. int mid = highStart - 1;
  18. int num = upperBound - lowStart + 1;
  19. while(lowStart<=mid && highStart<=upperBound) {
  20. if(array[lowStart] < array[highStart]) {
  21. data[j++] = array[lowStart++];
  22. } else {
  23. data[j++] = array[highStart++];
  24. }
  25. }
  26. while(lowStart<=mid) {
  27. data[j++] = array[lowStart++];
  28. }
  29. while(highStart<=upperBound) {
  30. data[j++] = array[highStart++];
  31. }
  32. for(j=0; j<num; j++) {
  33. array[lowBound+j] = data[j];
  34. }
  35. }
public void mergeSort() {
int[] newArray = new int[index];
recMergeSort(newArray, 0, index-1); } private void recMergeSort(int[] data, int low, int upper) {
if(low == upper) {
return;
}
int mid = (low + upper)/2;
recMergeSort(data, mid+1, upper);
recMergeSort(data, low, mid);
merge(data, low, mid+1, upper);
} private void merge(int[] data, int lowStart, int highStart, int upperBound) {
int j = 0;
int lowBound = lowStart;
int mid = highStart - 1;
int num = upperBound - lowStart + 1; while(lowStart<=mid && highStart<=upperBound) {
if(array[lowStart] < array[highStart]) {
data[j++] = array[lowStart++];
} else {
data[j++] = array[highStart++];
}
} while(lowStart<=mid) {
data[j++] = array[lowStart++];
} while(highStart<=upperBound) {
data[j++] = array[highStart++];
} for(j=0; j<num; j++) {
array[lowBound+j] = data[j];
}
}

5、希尔排序

希尔排序是一种高级排序,它是由插入排序进化来的,插入排序是将未排的数据依次与前面已排好的数据进行比较移动,这样如果一个较小的数排在靠后的位置,那么要找到这个数的正确位置就要进行较多次移动。希尔排序改进了这种方式,它将每次比较的间隔扩大,排过一次之后数据就分阶段有序了,之后逐渐缩小这个间隔再进行排序。这样做的目的就是让数据一开始可以在一个较大的范围内进行移动,待基本有序后数据的移动量就小了很多。

  1. public void shellSort() {
  2. int in, out;
  3. int h = 1;
  4. int temp;
  5. while(h < index/3) {
  6. h = h*3+1;
  7. }
  8. while(h>0) {
  9. for(out=h; out<index; ++out) {
  10. temp = array[out];
  11. in = out;
  12. while(in>h-1 && array[in-h] > temp) {
  13. array[in] = array[in-h];
  14. in -=h;
  15. }
  16. array[in] = temp;
  17. }
  18. h = (h-1)/3;
  19. }
  20. }
public void shellSort() {
int in, out;
int h = 1;
int temp;
while(h < index/3) {
h = h*3+1;
}
while(h>0) {
for(out=h; out<index; ++out) {
temp = array[out];
in = out;
while(in>h-1 && array[in-h] > temp) {
array[in] = array[in-h];
in -=h;
}
array[in] = temp;
}
h = (h-1)/3;
}
}

希尔排序中关键是对数据间隔h的选择,一个间隔序列是由Knuth提出的,即h=h*3+1,h的初始值为1,这是希尔排序中最优的间隔序列。

6、快速排序

快速排序是一种广泛使用的排序方法,效率可以达到O(NlogN),快速排序的原理是确定一个中间值pivot,将所有小于pivot的数据放在左侧,大于pivot的值放在右侧,之后再对左右两侧分别采取这种策略进行排序,直到这个过程结束。

  1. private int partition(int left, int right, int pivot) {
  2. int leftPtr = left;
  3. int rightPtr = right-1;
  4. while(true) {
  5. while(array[++leftPtr] < pivot) ;
  6. while(array[--rightPtr] > pivot);
  7. if(leftPtr >= rightPtr) {
  8. break;
  9. } else {
  10. swap(leftPtr, rightPtr);
  11. }
  12. }
  13. swap(leftPtr, right-1);
  14. return leftPtr;
  15. }
  16. private int median(int left, int right) {
  17. int center = (left+right)/2;
  18. if(array[left]>array[center]) {
  19. swap(left, center);
  20. }
  21. if(array[left]>array[right]) {
  22. swap(left, right);
  23. }
  24. if(array[center]>array[right]) {
  25. swap(center, right);
  26. }
  27. swap(center, right-1);
  28. return array[right-1];
  29. }
  30. private void manulSort(int left, int right) {
  31. int size = right-left+1;
  32. if(size <= 1) return;
  33. if(size == 2) {
  34. if(array[left]>array[right]) swap(left, right);
  35. } else {
  36. if(array[left]>array[right-1]) swap(left, right-1);
  37. if(array[left]>array[right]) swap(left, right);
  38. if(array[right-1]>array[right]) swap(right-1, right);
  39. }
  40. }
  41. private void recQuickSort(int left, int right) {
  42. int size = right-left+1;
  43. if(size<=3) {
  44. manulSort(left, right);
  45. } else {
  46. int pivot = median(left, right);
  47. int partition = partition(left, right, pivot);
  48. recQuickSort(left, partition-1);
  49. recQuickSort(partition+1, right);
  50. }
  51. }
  52. public void quickSort() {
  53. recQuickSort(0, index-1);
  54. }
private int partition(int left, int right, int pivot) {
int leftPtr = left;
int rightPtr = right-1;
while(true) {
while(array[++leftPtr] < pivot) ;
while(array[--rightPtr] > pivot);
if(leftPtr >= rightPtr) {
break;
} else {
swap(leftPtr, rightPtr);
}
}
swap(leftPtr, right-1);
return leftPtr;
} private int median(int left, int right) {
int center = (left+right)/2;
if(array[left]>array[center]) {
swap(left, center);
}
if(array[left]>array[right]) {
swap(left, right);
}
if(array[center]>array[right]) {
swap(center, right);
}
swap(center, right-1);
return array[right-1];
} private void manulSort(int left, int right) {
int size = right-left+1;
if(size <= 1) return;
if(size == 2) {
if(array[left]>array[right]) swap(left, right);
} else {
if(array[left]>array[right-1]) swap(left, right-1);
if(array[left]>array[right]) swap(left, right);
if(array[right-1]>array[right]) swap(right-1, right);
}
} private void recQuickSort(int left, int right) {
int size = right-left+1;
if(size<=3) {
manulSort(left, right);
} else {
int pivot = median(left, right);
int partition = partition(left, right, pivot);
recQuickSort(left, partition-1);
recQuickSort(partition+1, right);
} } public void quickSort() {
recQuickSort(0, index-1);
}

快速排序的关键是确定中间值pivot,如果中间值选取的不好,会使快速排序的效率降到O(N^2)。上面的例子采用了三选一的策略来确定中间值,即在要排序的数据中选择左端、中间和右端三个数据后比较取中间值;还有在数据量较小时,比如小于三个则直接手动排序。

快速排序选中间值实际上采用的是分治的思想,对数据的准确划分才能达到最高的效率,更深层的原理可以去看这篇文章

Java排序算法总结的更多相关文章

  1. 常用Java排序算法

    常用Java排序算法 冒泡排序 .选择排序.快速排序 package com.javaee.corejava; public class DataSort { public DataSort() { ...

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

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

  3. java排序算法(一):概述

    java排序算法(一)概述 排序是程序开发中一种非常常见的操作,对一组任意的数据元素(活记录)经过排序操作后,就可以把它们变成一组按关键字排序的一组有序序列 对一个排序的算法来说,一般从下面三个方面来 ...

  4. java排序算法(十):桶式排序

    java排序算法(十):桶式排序 桶式排序不再是一种基于比较的排序方法,它是一种比较巧妙的排序方式,但这种排序方式需要待排序的序列满足以下两个特征: 待排序列所有的值处于一个可枚举的范围之类: 待排序 ...

  5. java排序算法(九):归并排序

    java排序算法(九):归并排序

  6. java排序算法(八):希尔排序(shell排序)

    java排序算法(八):希尔排序(shell排序) 希尔排序(缩小增量法)属于插入类排序,由shell提出,希尔排序对直接插入排序进行了简单的改进,它通过加大插入排序中元素之间的间隔,并在这些有间隔的 ...

  7. java排序算法(七):折半插入排序

    java排序算法(七):折半插入排序 折半插入排序法又称为二分插入排序法,是直接插入排序法的改良版本,也需要执行i-1趟插入.不同之处在于第i趟插入.先找出第i+1个元素应该插入的位置.假设前i个数据 ...

  8. java排序算法(六):直接插入排序

    java排序算法(六):直接插入排序 直接插入排序的基本操作就是将待的数据元素按其关键字的大小插入到前面的有序序列中 直接插入排序时间效率并不高,如果在最坏的情况下,所有元素的比较次数的总和为(0+1 ...

  9. java排序算法(五):快速排序

    java排序算法(五):快速排序 快速排序是一个速度非常快的交换排序算法,它的基本思路很简单,从待排的数据序列中任取一个数据(如第一个数据)作为分界值,所有比它小的元素放到左边.所有比它大的元素放到右 ...

  10. java排序算法(四):冒泡排序

    java排序算法(四):冒泡排序 冒泡排序是计算机的一种排序方法,它的时间复杂度是o(n^2),虽然不及堆排序.快速排序o(nlogn,底数为2).但是有两个优点 1.编程复杂度很低.很容易写出代码 ...

随机推荐

  1. 关于neo4j的嵌入式和驱动包模式该如何选择,还请解惑

    看了网上的一些资料和Neo4j权威指南这本书.与图遍历相关的介绍都是基于嵌入式模式下的java Api.但是个人觉得在实际的项目中,嵌入式的模式,代码必须放在数据库所在服务器上,且服务器的启停操作都在 ...

  2. for循环取出每个i的值

    <!DOCTYPE html> <html> <head> <title></title> </head> <body&g ...

  3. DLedger —基于 raft 协议的 commitlog 存储库

    “点击获取上云帮助文档” 尊敬的阿里云用户: 您好!为方便您试用开源 RocketMQ 客户端访问阿里云MQ,我们申请了专门的优惠券,优惠券可以直接抵扣金额.请填写下您公司账号信息,点击上图,了解更多 ...

  4. 杨柳絮-Info:菏泽多措并举治理杨柳絮 5年内实现“有絮不成灾”

    ylbtech-杨柳絮-Info:菏泽多措并举治理杨柳絮 5年内实现“有絮不成灾” 1.返回顶部 1. 菏泽多措并举治理杨柳絮 5年内实现“有絮不成灾” 2019年04月09日 11:44  来源:大 ...

  5. Linux下备份Mysql所有数据库

    需求:备份除了mysql系统数据库的所有数据库 以下为Shell脚本,只需要修改用户密码即可 MYSQL_USER=root MYSQL_PASS=123456 MYSQL_CONN="-u ...

  6. go strcut 封装

    package model import "fmt" type person struct { Name string age int //其它包不能直接访问.. sal floa ...

  7. Spring Boot → 06:项目实战-账单管理系统

    Spring Boot → 06:项目实战-账单管理系统

  8. oracle-Normal

    从shutdown normal命令发布起, 禁止建立任何新的oracle连接. 数据库将等到所有用户都被断开后再继续关闭过程. 等待当前所有已连接的用户断开与数据库的连接

  9. startActivity 流程图

  10. JavaScript--函数对象的属性caller与callee

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...