1. 冒泡排序

冒泡排序Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

 int[] array = {5, 4, 3, 2, 1};

 boolean isChanged = false;
for (int i = 0; i < array.length; i++) {
isChanged = false; for (int j = 0; j < (array.length - i - 1); j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp; isChanged = true;
}
} if (!isChanged) {
break;
}
}
四次遍历
4 3 2 1 5
3 2 1 4 5
2 1 3 4 5
1 2 3 4 5
最大比较次数: n(n-1)/2 时间复杂度(最坏情况): O(2^n)
最小比较次数: n-1 时间复杂度(最好情况): O(n)

2. 快速排序

是由东尼·霍尔所发展的一种排序算法   基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

    public static void main(String[] args) {
// 快速排序
int[] array = {8, 2, 4 ,7 ,1 ,9 ,3 ,6, 5};
sortMe(array, 0, array.length-1);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + ",");
}
} public static void sortMe(int[] array, int low,int high){
if(low < high){
// 将list数组进行一分为二
int middle = getMiddle(array, low, high);
// 对低字表进行递归排序
sortMe(array, low, middle-1);
// 对高字表进行递归排序
sortMe(array, middle+1, high);
}
} public static int getMiddle(int[] array, int low,int high){
// 数组的第一个作为中轴
int temp = array[low];
while(low < high){
while(low < high && array[high] > temp){
high--;
} // 比中轴小的记录移到低端
array[low] = array[high]; while(low < high && array[low] <= temp){
low++;
} // 比中轴大的记录移到高端
array[high] = array[low];
} array[low] = temp; //中轴记录到尾 return low; //返回中轴的位置
}

3. 直接插入排序

1、算法概念。

每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。

2、算法思想。

 假设待排序的记录存放在数组R[1..n]中。初始时,R[1]自成1个有序区,无序区为R[2..n]。从i=2起直至i=n为止,依次将R[i]插入当前的有序区R[1..i-1]中,生成含n个记录的有序区。

3、实现思路。

①用一个临时变量temp存储第i个元素(i>=1,下标从0开始)。

②比较R[i] 和R[i+1],如果R[i+1].compareTo(R[i])<0,则R[i+1] = R[i],即比R[i+1]的集合元素依次往右移动一个单位。

③将temp的值赋给R[i].

 public static void main(String[] args) {
// 直接插入排序
int[] array = {8, 2, 4 ,7 ,1 ,9 ,3 ,6, 5};
insertSort(array); for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + ",");
}
} public static void insertSort(int[] data)
{
int length = data.length; for (int i = 1; i < length; i++)
{
int tmp = data[i];
if (tmp < data[i - 1])
{
int j = i - 1;
for (; j >= 0 && data[j] > tmp; j--)
{
data[j + 1] = data[j];
}
data[j + 1] = tmp;
}
}
}

  

4. 堆排序

堆排序的思想

利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单。

其基本思想为(大顶堆):

1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无序区;

2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];

3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

操作过程如下:

1)初始化堆:将R[1..n]构造为堆;

2)将当前无序区的堆顶元素R[1]同该区间的最后一个记录交换,然后将新的无序区调整为新的堆。

因此对于堆排序,最重要的两个操作就是构造初始堆和调整堆,其实构造初始堆事实上也是调整堆的过程,只不过构造初始堆是对所有的非叶节点都进行调整。

下面举例说明:

给定一个整形数组a[]={16,7,3,20,17,8},对其进行堆排序。

首先根据该数组元素构建一个完全二叉树,得到

 

然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:

20和16交换后导致16不满足堆的性质,因此需重新调整

这样就得到了初始堆。

即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。

此时3位于堆顶不满堆的性质,则需调整继续调整

 这样整个区间便已经有序了。
    从上述过程可知,堆排序其实也是一种选择排序,是一种树形选择排序。只不过直接选择排序中,为了从R[1...n]中选择最大记录,需比较n-1次,然后从R[1...n-2]中选择最大记录需比较n-2次。事实上这n-2次比较中有很多已经在前面的n-1次比较中已经做过,而树形选择排序恰好利用树形的特点保存了部分前面的比较结果,因此可以减少比较次数。对于n个关键字序列,最坏情况下每个节点需比较log2(n)次,因此其最坏情况下时间复杂度为nlogn。堆排序为不稳定排序,不适合记录较少的排序。
 private static int[] sort = new int[] {
1, 0, 10, 20, 3, 5, 6, 4, 9, 8, 12,
17, 34, 11
}; public static void main(String[] args) {
buildMaxHeapify(sort);
heapSort(sort);
print(sort);
} private static void buildMaxHeapify(int[] data) {
// 没有子节点的才需要创建最大堆,从最后一个的父节点开始
int startIndex = getParentIndex(data.length - 1);
// 从尾端开始创建最大堆,每次都是正确的堆
for (int i = startIndex; i >= 0; i--) {
maxHeapify(data, data.length, i);
}
} /**
* 创建最大堆
*
* @paramdata
* @paramheapSize需要创建最大堆的大小,一般在sort的时候用到,因为最多值放在末尾,末尾就不再归入最大堆了
* @paramindex当前需要创建最大堆的位置
*/
private static void maxHeapify(int[] data, int heapSize, int index) {
// 当前点与左右子节点比较
int left = getChildLeftIndex(index);
int right = getChildRightIndex(index); int largest = index;
if (left < heapSize && data[index] < data[left]) {
largest = left;
}
if (right < heapSize && data[largest] < data[right]) {
largest = right;
}
// 得到最大值后可能需要交换,如果交换了,其子节点可能就不是最大堆了,需要重新调整
if (largest != index) {
int temp = data[index];
data[index] = data[largest];
data[largest] = temp;
maxHeapify(data, heapSize, largest);
}
} /**
* 排序,最大值放在末尾,data虽然是最大堆,在排序后就成了递增的
*
* @paramdata
*/
private static void heapSort(int[] data) {
// 末尾与头交换,交换后调整最大堆
for (int i = data.length - 1; i > 0; i--) {
int temp = data[0];
data[0] = data[i];
data[i] = temp;
maxHeapify(data, i, 0);
}
} /**
* 父节点位置
*
* @paramcurrent
* @return
*/
private static int getParentIndex(int current) {
return (current - 1) >> 1;
} /**
* 左子节点position注意括号,加法优先级更高
*
* @paramcurrent
* @return
*/
private static int getChildLeftIndex(int current) {
return (current << 1) + 1;
} /**
* 右子节点position
*
* @paramcurrent
* @return
*/
private static int getChildRightIndex(int current) {
return (current << 1) + 2;
} private static void print(int[] data) {
int pre = -2;
for (int i = 0; i < data.length; i++) {
if (pre < (int) getLog(i + 1)) {
pre = (int) getLog(i + 1);
System.out.println();
}
System.out.print(data[i] + "|");
}
} /**
* 以2为底的对数
*
* @paramparam
* @return
*/
private static double getLog(double param) {
return Math.log(param) / Math.log(2);
}

  5.  归并排序

九大排序算法Demo的更多相关文章

  1. 九大排序算法Java实现

    之前学习数据结构与算法时花了三天时间整理九大排序算法,并采用Java语言来实现,今天第一次写博客,刚好可以把这些东西从总结的文档中拿出来与大家分享一下,同时作为自己以后的备忘录. 1.排序算法时间复杂 ...

  2. C语言实现九大排序算法

    C语言实现九大排序算法 直接插入排序 折半插入排序 希尔排序 冒泡排序 快速排序 直接选择排序 堆排序 归并排序 基数排序 C语言实现九大排序算法 直接插入排序 将数组分为两个部分,一个是有序部分,一 ...

  3. 【转】九大排序算法-C语言实现及详解

    概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大, ...

  4. 你需要知道的九大排序算法【Python实现】之堆排序

    六.堆排序 ​堆排序是一种树形选择排序,是对直接选择排序的有效改进. ​堆的定义下:具有n个元素的序列 (h1,h2,...,hn),当且仅当满足(hi>=h2i,hi>=2i+1)或(h ...

  5. 你需要知道的九大排序算法【Python实现】之插入排序

    三.插入排序 基本思想:插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2).是稳定的排序方法.插入算 ...

  6. 你需要知道的九大排序算法【Python实现】之基数排序

    八.基数排序 基本思想:基数排序(radix sort)属于"分配式排序"(distribution sort),又称"桶子法"(bucket sort)或bi ...

  7. 你需要知道的九大排序算法【Python实现】之快速排序

    五.快速排序 基本思想:  通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则分别对这两部分继续进行排序,直到整个序列有序. 算法实现: ​ #coding: ...

  8. 你需要知道的九大排序算法【Python实现】之归并排序

    四.归并排序 基本思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列.归并过程:比 ...

  9. 你需要知道的九大排序算法【Python实现】之冒泡排序

    二.冒泡排序 基本思想:它的思路很有特点循环,两两向后比较.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数 ...

随机推荐

  1. 团队作业8——第二次项目冲刺(Beta阶段)5.25

    1.当天站立式会议照片 会议内容: 本次会议为第六次会议 本次会议在陆大楼3楼召开,本次会议内容: ①:检查总结上次任务完成情况 ②:安排今天的分工 ③:对昨天的问题进行讨论 ④:遇到困难,及时群里反 ...

  2. 201521123107 《Java程序设计》第12周学习总结

    第12周-流与文件 1.本周学习总结 2.书面作业 将Student对象(属性:int id, String name,int age,double grade)写入文件student.data.从文 ...

  3. 团队作业10--事后分析(Beta版本)

    设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件的作用是帮助用户实现准确快速的电子文档查重,我们对软件的定义是电子文档查重系统,即通过文 ...

  4. 201521123083《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 2. 书面作业 1. 代码阅读:Child压缩包内源代码 1.1 com.par ...

  5. 201521123055 《Java程序设计》第5周学习总结

    1. 本章学习总结 2. 书面作业 Q1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误.并分析输出结果. 1. ...

  6. 201521123025<<java程序设计>>第4周学习总结

    Q1. 本周学习总结 Q2.书面作业 1.注释的应用 使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看.(截图) 2.面向对象设计(大作业1,非常重要) 2.1 将在网上 ...

  7. 201521123012 《Java程序设计》第十三周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec ...

  8. 201521123085《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 finally 题目4-2 1.1 截图你的提交结果(出现学 ...

  9. sourcetree和gitlab配置图解

    一.前期准备安装 1.git客户端(1.产生gitlab服务端和本地git相互传输时所需要校验的私钥和公钥    2.直接在Idea中使用git提交和push代码,当然也可以用sourcetree提交 ...

  10. 【二】刚学Python的几道简单练习题

    python交友娱乐会所:613176398 1.使用while循环输入 1 2 3 4 5 6     8 9 10 2.求1-100的所有数的和 3.输出 1-100 内的所有奇数 4.输出 1- ...