一、各个算法的时间复杂度

二,具体实现

1、直接选择排序

基本思想:在长度为n的序列中,第一次遍历找到该序列的最小值,替换掉第一个元素,接着从第二个元素开始遍历,找到剩余序列中的最小值,替换掉第二个元素,以此类推,直到剩余序列中剩下一个元素为止。

时间复杂度:O(n2)

 代码实现:

  public static void selectSort(int[] array){
//从序列的第一个元素开始遍历
for(int i=0;i<array.length;i++){
int p=i;//用来记录最小元素的下标
//在剩余序列中查找最小元素
for(int j=i;j<array.length;j++){
//当查找到比当前值小的元素,用p记录其小标
if(array[p]>array[j]){
p=j;
}
}
//如果p不等于刚开始的值,说明在遍历过程中,有查到比起始值小的元素
//否则,起始值就是剩余序列中的最小值,不用进行调整
if(p!=i){
int tmp=array[i];
array[i]=array[p];
array[p]=tmp;
}
}
}
2、堆排序

基本思想:将待排序列建成一个大根堆,同时保证根结点的左右子孩子也是一个大根堆,此时整个树的根节点就是该序列的最大值,然后让根节点与最底层的最后一个孩子的值进行交换后,接着将树缩小范围,同时将树的剩余部分又调整成一个大根堆,同时保证根结点的左右子孩子也是一个大根堆,然后让根节点与剩余树的最底层的最后一个孩子的值进行交换后。依次类推,直到剩余树中只剩一个元素为止。

时间复杂度:

步骤:

*     1.先从最底层的父亲节点开始,判断是否有左右孩子,若有则找出孩子中的较大值,与父亲节点相比较,
* 若值大于父亲节点的值,则与父亲节点值进行交换。
* 2.然后将父亲节点代替了的孩子的子孩子,又作为父亲结点也进行上述的调整。
* (只对替代了父亲节点的孩子进行调整,因为对于另一个孩子,其没有与父亲结点值进行交换,而且在底下往上
* 调整的时候已经保证了该孩子结点的值是大于它的子孩子的,所以无需在进行调整。)
* 3.当对整棵树调整完后,此时树的根节点存放的值就是整棵树中的最大值。
* 4.接着将存放最大值的这个根结点与最后的那个叶子结点的值交换,并将树的大小减一,然后又将根节点
* 和它的子节点进行调整,以致根节点又存放着整棵树的最大值。以此类推,直到树的大小只剩一个,这时候
* 整棵树从上到下就是按从小到大的顺序排列的。

扩充:

代码实现:

     //堆排序
public static void bigHeapSort(int[] array){
if(array == null || array.length == 0){
return;
}
//建立大根堆
//第一次从最底层的父亲节点开始调整,保证各个父亲结点的值是大于等于孩子的值的,且根结点保存整棵树的最大值。
for(int i=(array.length-1-1)/2; i >= 0; i--){ //(不管是左孩子还是右孩子,通过减一除2都可以求的其父亲结点。)
//给i赋初值为(array.length-1-1)/2,是因为根据完全二叉树原理,该结点有孩子,则一定有左孩子,但不一定有右孩子
// 所以用左孩子来求父亲结点
adjust(array, i, array.length-1);
}
//将根节点与最后的叶子结点进行交换,然后将叶子节点范围缩小
for(int i=array.length-1; i>0; i--){
int tmp = array[0];
array[0] =array[i];
array[i] = tmp;
//交换完后,缩小范围,接着调整
adjust(array, 0, i-1);
}
}
//堆调整过程
public static void adjust(int[] array, int start, int end){
int tmp = array[start];
//start是根节点,当存在左孩子时,说明该结点有孩子,找出节点孩子的最大值
for(int i=2*start+1; i<=end; i=2*i+1){
//判断是否有右孩子,找出左右孩子的最大值
if(i+1 <= end && array[i] < array[i+1]){//右孩子存在,且右孩子值大于左孩子
i++; // i保存右孩子的下标
}
//若右孩子不存在,或找到了孩子中的最大值
if(array[i] > tmp){ //将孩子的值又与父亲结点的值进行比较,若大于父亲结点,则交换
array[start] = array[i];
array[i]=tmp;
start = i;//更新start,保存为替代了父亲结点的孩子的下标,然后对它的孩子进行调整
//因为之前调整时,只能保证它的结点值是大于它的孩子的。但不能保证替下来的父亲结点的值也是大于它的孩子的值。
}else{
break;
}
} }
3、直接插入排序

基本思想:对待排序列元素进行一个一个的遍历,将遍历到哪个元素,就将那个元素插到前面已排好序的队列的从后往前遍历的第一个小于它的元素的后面。

时间复杂度:

  public static void InsertSort(int[] array){
for(int i=0;i<array.length;i++){//对待排元素序列从前往后进行遍历
int tmp=array[i];//记录当前待排元素的值
int j;
for( j=i-1;j>=0;j--){//对排好序的队列从后往前遍历,找第一个小于它的元素
if(array[j]<array[i]){
break; //找到后退出,此时j+1号位就是当前待排元素要插入的位置
}
}
for(int k=i;k>j+1;k--){//在排好序的队列中,将j号后面的元素统一移到下一位
array[k]=array[k-1]; //腾出j+1号位置
}
array[j+1]=tmp; //将当前待排元素插到j+1号位置
} }
4、希尔

 基本思想:对于n个待排序的数列,取一个小于n的整数gap(gap被称为步长)将待排序元素分成若干个组子序列,所有距离为gap的倍数的记录放在同一个组中;然后,对各组内的元素进行直接插入排序。 这一趟排序完成之后,每一个组的元素都是有序的。然后减小gap的值,并重复执行上述的分组和排序。重复这样的操作,当gap=1时,整个数列就是有序的。

步骤图:

 代码实现:

 public static void shellSort(int[] array){
int lenght=array.length;
while (true){
lenght=lenght/2;
for(int i=0;i<lenght;i++){ //对所有元素进行排序
for(int j=i+lenght;j<array.length;j+=lenght){//对每个组中的待排元素进行遍历(第一次是从第二个元素开始的)
for(int k=j;k>i;k-=lenght){//对每个组内以排好序的元素进行遍历,
if(array[k]<array[k-lenght]){
int tmp=array[k-lenght];
array[k-lenght]=array[k];
array[k]=tmp;
}else {
break;
}
}
} }
if(lenght==1){
break;
}
}
}
 5、冒泡排序

基本思想:对待排序列进行遍历,遍历的同时比较相邻的两个数据,如果前一个元素大于后一个,交换位置,一趟遍历完成后,会将序列元素的最大值移到最后,然后缩小范围,接着进行第二趟遍历,直到范围中元素只剩一个为止。

时间复杂度:

步骤图:

代码实现:

   public static void  bubbleSort(int[] array){
for(int i=0;i<array.length;i++){
for(int j=0;j<array.length-i-1;j++){
//如果前一个值大于后一个,则调整两者位置
if(array[j]>array[j+1]){
int tmp=array[j];
array[j]=array[j+1];
array[j+1]=tmp;
}
}
}
}
6.快速排序

基本思想:    1.从队列中取一个数作为它的基准(一般选取队列的第一个值)

       2.将所有比基准大的元素放到它的右边分区,比基准小的元素放到她的左边分区

        3.对左右两个分区重复第二步,直到各个分区只剩一个元素

步骤图:

                                   

                              

 代码实现:

    public static void  quickSort(int[] array,int begin,int end ){
if(array==null&&array.length==0){
return;
}
int left=begin,right=end;
int p=array[left];//定义基准
while (left<right) { //一趟遍历结束的条件
// 从后往前遍历,找比p小的
while (left < right && array[right] >= p) {
right--;
}
array[left] = array[right];//将查找到小的元素,赋给左指针(此时右指针元素多余)
//从前往后遍历,找比p大的
while (left < right && array[left] <= p) {
left++;
}
array[right]=array[left]; ///将查找到大的元素,赋给右指针(此时左指针元素多余)
array[left]=p;
}
//left-1>begin 说明此时左边分区的元素大于一个,要继续排。
if(left-1>begin) {
quickSort(array, begin, left-1); //
}
//同理
if(right+1<end){
quickSort(array,right+1,end);
} }
7.归并排序

思想:将一个有n个记录的无序数组,不断的分割,直到每个分组中只剩一个元素(递的过程)

然后又将相邻的两个数组的元素分别排好序后进行合并(归的过程)

步骤图:

代码实现:

    public static void mergeSort(int[] array1,int begin,int end){
if(array1==null&&array1.length==0){
return;
}
int first=begin;
int last=end;
if(first>=last){
return;
}
int mid=(first+last)/2;
mergeSort(array1,first,mid);
mergeSort(array1,mid+1,last);
merge(array1,first,mid,last);
}
public static void merge(int[] array1,int first,int mid,int last){
int[] array2=new int[last-first+1];
int i=first;
int m=mid;
int j=mid+1;
int n=last;
int k=0;
//当两个数组都还没有空
while (i<=m && j<=n){
if(array1[i]<=array1[j]){
array2[k++]=array1[i++];
}else {
array2[k++] = array1[j++];
}
}
while (i<=m){
array2[k]=array1[i];
k++;
i++;
}
while (j<=n){
array2[k]=array1[j];
k++;
j++;
}
for(int s=0;s<last-first+1;s++){
array1[first+s]=array2[s];
}
}
												

Java的七大排序的更多相关文章

  1. JAVA:数组,排序,查找<4>

    一.数组 1.一维数组 (1).数组的定义 数据类型 数组名[]=new 数据类型[大小] public class Demo1 { public static void main(String[] ...

  2. Java中的排序算法(2)

    Java中的排序算法(2) * 快速排序 * 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists). * 步骤为: * 1. 从数 ...

  3. (转)白话经典算法系列之八 MoreWindows白话经典算法之七大排序总结篇

    在我的博客对冒泡排序,直接插入排序,直接选择排序,希尔排序,归并排序,快速排序和堆排序这七种常用的排序方法进行了详细的讲解,并做成了电子书以供大家下载.下载地址为:http://download.cs ...

  4. 排序算法:七大排序算法的PHP实现

    由于最近在找工作,面试中难免会遇到一些算法题,所以就用PHP把七大排序算法都实现了一遍,也当做是一种复习于沉淀. 冒泡排序 2. 选择排序 3. 插入排序 4. 快速排序 5. 希尔排序 6. 归并排 ...

  5. Java实现常见排序算法

    常见的排序算法有冒泡排序.选择排序.插入排序.堆排序.归并排序.快速排序.希尔排序.基数排序.计数排序,下面通过Java实现这些排序 1.冒泡排序 package com.buaa; import j ...

  6. Comparable与Comparator,java中的排序与比较

    1:比较和排序的概念 比较:两个实体类之间按>,=,<进行比较. 排序:在集合类中,对集合类中的实体进行排序.排序基于的算法基于实体类提供的比较函数. 基本型别都提供了默认的比较算法,如s ...

  7. Java之List排序出错

    Java之List排序出错 Bound mismatch: The generic method sort(List<T>) of type Collections is not appl ...

  8. Java进阶(三十九)Java集合类的排序,查找,替换操作

    Java进阶(三十九)Java集合类的排序,查找,替换操作 前言 在Java方向校招过程中,经常会遇到将输入转换为数组的情况,而我们通常使用ArrayList来表示动态数组.获取到ArrayList对 ...

  9. java过滤器(过滤器排序)

    java过滤器(过滤器排序) 定义过滤器顺序是很简单的:匹配请求的过滤器将按照它们出现在部署描述符或者编程式配置中的顺序添加到过滤器链中(记住,如果同时再部署描述符或者编程式配置中设置了一些过滤器,那 ...

随机推荐

  1. 使用Razor 使用Razor表达式处理命名空间 精通ASP-NET-MVC-5-弗瑞曼

  2. NOI4.6 1455:An Easy Problem

    描述 As we known, data stored in the computers is in binary form. The problem we discuss now is about ...

  3. FreeImage 结合 VB6 使用技巧

    1.图片(Bitmap)改变为32位使用FreeImage_ConvertColorDepth函数.图片半透明绘制需要图片(Bitmap)是32位的. 2.图片(Bitmap)的半透明绘制使用函数:F ...

  4. axios用post传参,后端无法获取参数问题

    最近用vue+nodejs写项目,前端使用axios向后台传参,发现后台接收不到参数. 后台是node+express框架,然后使用了body-parser包接收参数,配置如下: const expr ...

  5. ImportError: Failed to import pydot. You must install pydot and graphviz for `pydotprint` to work.

    用了pip install pydot; pip install graphviz都不行 去网上查了才发现window下要去https://graphviz.gitlab.io/下载windows版本 ...

  6. UML类图的情话诉说

    你知道吗这个世界是个繁杂而又简单的世界 你我在冥冥中都有联系 有时候,你像我的妈妈一样,对你依赖满满, 没有你我不知道何去何从(依赖) 有时候,看你,真如我亲爱孩子般,想一直拥你入我怀抱,但我知道终究 ...

  7. CSS学习笔记--Div+Css布局(div+span以及盒模型)

    1.DIV与SPAN 1.1简介 1.DIV和SPAN在整个HTML标记中,没有任何意义,他们的存在就是为了应用CSS样式 2.DIV和span的区别在与,span是内联元素,div是块级元素 内联元 ...

  8. FFmpeg被声明为已否决的解决方案

    参考雷神的最简单的打印Hello World的程序: #include <stdio.h> #include <string.h> extern "C" { ...

  9. QtGui实现计算圆的面积

    dialog.h #ifndef DIALOG_H #define DIALOG_H #include <QtWidgets/QDialog> #include <QtWidgets ...

  10. 使用纯C++迭代器编写归并排序

    第一次尝试用C++迭代器编写算法,使用的是纯迭代器 void mergeSort(vector<int>::iterator beg, vector<int>::iterato ...