排序分为内部排序和外部排序
内部排序是把待排数据元素全部调入内存中进行的排序。
外部排序是因数量太大,把数据元素分批导入内存,排好序后再分批导出到磁盘和磁带外存介质上的排序方法。

比较排序算法优劣的标准:
(1)时间复杂度:它主要是分析记录关键字的比较次数和记录的移动次数
(2)空间复杂度 :算法中使用的内存辅助空间的多少
(3)稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的

内部排序:
1)插入排序(直接插入排序、希尔排序)
2)交换排序(冒泡排序、快速排序)
3)选择排序(直接选择排序、堆排序)
4)归并排序
5)分配排序(基数排序)

插入排序的基本思想是:
每步将一个待排序的数据元素,按其关键码大小,插入到前面已经排好序的一组数据元素的适当位置上,直到数据元素全部插入为止。

常用的插入排序
(1)直接插入排序
(2)希尔排序

1.直接插入排序

其基本思想是:顺序地把待排序的数据元素按其关键字值的大小插入到已排序数据元素子集合的适当位置。

算法分析:
(1)时间效率: 因为在最坏情况下,所有元素的比较次数总和为(0+1+…+n-1)→O(n2)。其他情况下也要考虑移动元素的次数。 故时间复杂度为O(n2)
(2)空间效率:仅占用1个缓冲单元——O(1)
(3)算法的稳定性:稳定

[img]http://dl2.iteye.com/upload/attachment/0113/0890/60b4644e-455e-33f2-825d-f2509c2937b9.jpg[/img]

2.希尔(shell)排序(又称缩小增量排序)
(1)基本思想:把整个待排序的数据元素分成若干个小组,对同一小组内的数据元素用直接插入法排序;小组的个数逐次缩小,当完成了所有数据元素都在一个组内的排序后排序过程结束。
(2)技巧:小组的构成不是简单地“逐段分割”,而是将相隔某个增量dk的记录组成一个小组,让增量dk逐趟缩短(例如依次取5,3,1),直到dk=1为止。
(3)优点:让关键字值小的元素能很快前移,且序列若基本有序时,再用直接插入排序处理,时间效率会高很多。

[img]http://dl2.iteye.com/upload/attachment/0113/0892/ea32962b-436c-3089-ba2a-aa9b775de536.jpg[/img]

选择排序
基本思想是:每次从待排序的数据元素集合中选取关键字最小(或最大)的数据元素放到数据元素集合的最前(或最后),数据元素集合不断缩小,当数据元素集合为空时选择排序结束。
常用的选择排序算法:
(1)直接选择排序
(2)堆排序

1.直接选择排序
基本思想是:从待排序的数据元素集合中选取关键字最小的数据元素并将它与原始数据元素集合中的第一个数据元素交换位置;然后从不包括第一个位置上数据元素的集合中选取关键字最小的数据元素并将它与原始数据元素集合中的第二个数据元素交换位置;如此重复,直到数据元素集合中只剩一个数据元素为止。

优点:实现简单
缺点:每趟只能确定一个元素,表长为n时需要n-1趟

算法分析
时间效率: O(n2)——虽移动次数较少,但比较次数仍多。
空间效率:O(1)——没有附加单元(仅用到1个temp)
算法的稳定性:不稳定

[img]http://dl2.iteye.com/upload/attachment/0113/0894/411a34fa-d04b-3b0c-a2fd-9919cc651abd.jpg[/img]

2.堆排序
基本思想:把待排序的数据元素集合构成一个完全二叉树结构,则每次选择出一个最大(或最小)的数据元素只需比较完全二叉树的高度次,即log2n次,则排序算法的时间复杂度就是O(nlog2n)。

堆的定义
堆分为最大堆和最小堆两种。定义如下:
设数组a中存放了n个数据元素,数组下标从0开始,如果当数组下标2i+1<n时有:a[i].key≥a[2i+1].key(a[i].key≤a[2i+1].key);如果当数组下标2i+2<n时有:a[i].key≥a[2i+2].key (a[i].key≤a[2i+2].key),则这样的数据结构称为最大堆(最小堆)。

[img]http://dl2.iteye.com/upload/attachment/0113/0896/1c2d5717-0f50-3065-b9df-e79d88c636d8.jpg[/img]

性质:
(1)最大堆的根结点是堆中值最大的数据元素,最小堆的根结点是堆中值最小的数据元素,我们称堆的根结点元素为堆顶元素。
(2)对于最大堆,从根结点到每个叶结点的路径上,数据元素组成的序列都是递减有序的;对于最小堆,从根结点到每个叶结点的路径上,数据元素组成的序列都是递增有序的。

堆排序的基本思想是:
循环执行如下过程直到数组为空:
(1)把堆顶a[0]元素(为最大元素)和当前最大堆的最后一个元素交换;
(2)最大堆元素个数减1;
(3)由于第(1)步后根结点不再满足最大堆的定义,所以调整根结点使之满足最大堆的定义

[img]http://dl2.iteye.com/upload/attachment/0113/0898/ae74899e-13a0-3d56-bc7b-0db45db69a2a.jpg[/img]

算法分析:
时间效率:O(nlog2n)。因为整个排序过程中需要调用n-1次堆顶点的调整,而每次堆排序算法本身耗时为log2n;
空间效率:O(1)。仅在第二个for循环中交换记录时用到一个临时变量temp。
稳定性: 不稳定。
优点:对小文件效果不明显,但对大文件有效。

交换排序
基本思想是:利用交换数据元素的位置进行排序的方法。
交换排序的主要算法有:
1)冒泡排序
2)快速排序

1.冒泡排序
基本思想:每趟不断将数据元素两两比较,并按“前小后大”(或“前大后小”)规则交换。
优点:每趟结束时,不仅能挤出一个最大值到最后面位置,还能同时部分理顺其他元素;一旦下趟没有交换发生,还可以提前结束排序。

[img]http://dl2.iteye.com/upload/attachment/0113/0900/cf896ab7-4c48-3d9f-a14c-323db1263044.jpg[/img]

算法分析:
[img]http://dl2.iteye.com/upload/attachment/0113/0902/a7c9cd6c-bf60-35b9-9edd-bcc902aa9918.jpg[/img]

2 .快速排序
基本思想:从待排序列中任取一个元素 (例如取第一个) 作为中心,所有比它小的元素一律前放,所有比它大的元素一律后放,形成左右两个子表;然后再对各子表重新选择中心元素并依此规则调整,直到每个子表的元素只剩一个。此时便为有序序列了。
优点:因为每趟可以确定不止一个元素的位置,而且呈指数增加,所以特别快。

[img]http://dl2.iteye.com/upload/attachment/0113/0904/c1d9c633-9fd7-383c-8312-35a968ccc720.jpg[/img]

[img]http://dl2.iteye.com/upload/attachment/0113/0906/190b51f9-707b-3388-af4b-0acc750cc632.jpg[/img]

算法分析:
时间效率:O(nlog2n) —因为每趟确定的元素呈指数增加
空间效率:O(log2n)—因为递归要用堆栈
稳 定 性: 不 稳 定 —因为有跳跃式交换。

归并排序
归并排序主要是二路归并排序,基本思想是:可以把一个长度为n 的无序序列看成是 n 个长度为 1 的有序子序列 ,首先做两两归并,得到 n / 2 个长度为 2 的有序子序列 ;再做两两归并,…,如此重复,直到最后得到一个长度为 n 的有序序列。

[img]http://dl2.iteye.com/upload/attachment/0113/0908/ea005034-c50b-3209-b27e-1b77ef27ca36.jpg[/img]

基数排序
其基本思想是:
设待排序的数据元素关键字是m位d进制整数(不足m位的关键字在高位补0),设置d个桶,令其编号分别为0,1,2,…,d-1。首先按关键字最低位的数值依次把各数据元素放到相应的桶中,然后按照桶号从小到大和进入桶中数据元素的先后次序收集分配在各桶中的数据元素,这样就形成了数据元素集合的一个新的排列,我们称这样的一次排序过程为一次基数排序;再对一次基数排序得到的数据元素序列按关键字次低位的数值依次把各数据元素放到相应的桶中,然后按照桶号从小到大和进入桶中数据元素的先后次序收集分配在各桶中的数据元素;这样的过程重复进行,当完成了第m次基数排序后,就得到了排好序的数据元素序列。

[img]http://dl2.iteye.com/upload/attachment/0113/0910/036e03b5-7c2b-3739-91bd-ecfce89af13b.jpg[/img]

基数排序算法进出桶中的数据元素序列满足先进先出的原则,桶实际就是队列。实现基数排序算法时,有基于顺序队列和基于链式队列两种不同的实现方法。
在基于链式队列的基数排序算法中,可以把d个队列设计成一个队列数组(设队列数组名为tub),队列数组的每个元素中包括两个域: front域和rear域。front域用于指示队头,rear域用于指示队尾。当第i(i=0,1,2,…,d-1)个队列中有数据元素要放入时,就在队列数组的相应元素tub[i]中的队尾位置插入一个结点。基于链式队列基数排序算法的存储结构示意图如下图所示。

[img]http://dl2.iteye.com/upload/attachment/0113/0912/3e0b4c84-d14f-3444-a9b5-17aa1ec5a63f.jpg[/img]

基数排序算法分析
特点:不用比较和移动,改用分配和收集,时间效率高!
时间复杂度为:O (mn)。
空间复杂度:O(n).
稳定性:稳定。(一直前后有序)。

总结:
[img]http://dl2.iteye.com/upload/attachment/0113/0914/5496bd1b-6279-37a7-9b82-de15a542b3ca.jpg[/img]

java中具体代码实现

冒泡排序 简单选择排序 直接插入排序 希尔排序

import java.util.Random;

public class Demo {public static void main(String[] args) {

  int [] src=createArray(5);   System.out.println("********冒泡排序前数组原始数据:");  printArray(src);  System.out.println("********冒泡排序后:");    printArray(maopao(src));

    src=createArray(5);  System.out.println("********简单选择排序前数组原始数据:");    printArray(src);  System.out.println("********简单选择排序后:");  printArray(xuanze(src));

    src=createArray(5);  System.out.println("********直接插入排序前数组原始数据:");    printArray(src);  System.out.println("********直接插入排序后:");  printArray(charu(src));

    src=createArray(5); System.out.println("********希尔排序前数组原始数据:");  printArray(src);  System.out.println("********希尔排序后:");    printArray(shell(src));}//生成一个乱序的 指定长度的原始数组public static int[] createArray(int size){   //初始化数组   int [] x=new int[size];  for(int i=0;i<x.length;i++){        //创建一个随机对象        Random r=new Random();       x[i]=r.nextInt(100); }

   return x;}//打印出数组中的元素public static void printArray(int [] x){   //如果要打印的数组为null,则不打印   if(x==null){        return ;  } for(int i=0;i<x.length;i++){        System.out.println(x[i]); }}//冒泡排序public static int[] maopao(int [] x){   for(int i=0;i<x.length;i++){        for(int j=i+1;j<x.length;j++){         if(x[i]>x[j]){             int temp=x[j];               x[j]=x[i];               x[i]=temp;           }     } }  return x;}//简单选择排序public static int[] xuanze(int [] x){    for(int i=0;i<x.length;i++){        int lowerindex=i;        //找出最小的一个索引       for(int j=i+1;j<x.length;j++){         if(x[j]<x[lowerindex]){                lowerindex=j;            }     }     //交换   int temp=x[i];   x[i]=x[lowerindex];  x[lowerindex]=temp;     } return x;}//直接插入排序public static int[] charu(int [] x){  for(int i=1;i<x.length;i++){        for(int j=i;j>0;j--){         if(x[j]<x[j-1]){               int temp=x[j];                x[j]=x[j-1];                x[j-1]=temp;         }     } } return x;}//希尔排序public static int[] shell(int [] x){    //分组      for(int increment=x.length/2;increment>0;increment/=2){          //每个组内排序          for(int i=increment;i<x.length;i++){            int temp=x[i];               int j=0;             for(j=i;j>=increment;j-=increment){                 if(temp<x[j-increment]){                       x[j]=x[j-increment];                 }else {                    break;                 }               }             x[j]=temp;           }     } return x;}

}

快速排序

import java.util.Random;

public class kaisu {public static void main(String[] args) {   int [] src=createArray(5);   System.out.println("********快速排序前数组原始数据:");  printArray(src);  System.out.println("********快速排序后:");    printArray(kuaisu(src));}

public static int[] createArray(int size){ //初始化数组   int [] x=new int[size];  for(int i=0;i<x.length;i++){        //创建一个随机对象        Random r=new Random();       x[i]=r.nextInt(100); }

   return x;}public static void printArray(int [] x){    //如果要打印的数组为null,则不打印   if(x==null){        return ;  } for(int i=0;i<x.length;i++){        System.out.println(x[i]); }}public static int[] kuaisu(int [] x){        quick(x);     return x;}public static void quick(int [] x){    if(x.length>0){        quicksort(x,0,x.length-1);    }}public static void quicksort(int [] x,int low,int high){    //如果不加这个判断递归会无法退出导致堆栈溢出异常 if(low<high){      int middle=getmiddle(x,low,high);        quicksort(x,0,middle-1);      quicksort(x,middle+1,high);

    }}public static int getmiddle(int [] x,int low,int high){ int temp=x[low];//基准元素   while(low<high){       //找到比基准元素小的元素位置       while(low<high&&x[high]>=temp){            high--;       }     x[low]=x[high];      while(low<high&&x[low]<=temp){         low++;      }     x[high]=x[low];      } x[low]=temp; return low;}}

堆排序

import java.util.Random;

public class Heap {  public static void main(String[] args) {      int [] src=createArray(5);       System.out.println("********堆排序前数组原始数据:");       printArray(src);      System.out.println("********堆排序后:");     printArray(heap(src));    }

   public static int[] createArray(int size){        //初始化数组       int [] x=new int[size];      for(int i=0;i<x.length;i++){            //创建一个随机对象            Random r=new Random();           x[i]=r.nextInt(100);     }

       return x; } public static void printArray(int [] x){      //如果要打印的数组为null,则不打印       if(x==null){            return ;      }     for(int i=0;i<x.length;i++){            System.out.println(x[i]);     } } public static int[] heap(int [] x){        //循环建堆        for(int i=0;i<x.length;i++){           //建堆           buildMaxHeap(x,x.length-1-i);            //交换堆顶和最后一个元素             swap(x,0,x.length-1-i);                }         return x;    } //对x数组从0到lastIndex建大顶堆public static void buildMaxHeap(int [] x,int lastindex){  //从lastIndex处节点(最后一个节点)的父节点开始   for(int i=(lastindex-1)/2;i>=0;i--){     //k保存正在判断的节点      int k=i;   //如果当前k节点的子节点存在 while(k*2+1<=lastindex){      //k节点的左子节点的索引        int biggerindex=2*k+1;      //如果biggerIndex小于lastIndex        //即biggerIndex+1代表的k节点的右子节点存在        if(biggerindex<lastindex){          //若果右子节点的值较大             if(x[biggerindex]<x[biggerindex+1]){              //biggerIndex总是记录较大子节点的索引                 biggerindex++;          }     }      //如果k节点的值小于其较大的子节点的值         if(x[k]<x[biggerindex]){        //交换他们           swap(x,k,biggerindex);         //将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值          k=biggerindex;       }else {           break;        } }  }}//交换public static void swap(int[] x,int i,int j){        int temp=x[i];       x[i]=x[j];       x[j]=temp;   }}

归并排序

import java.util.Random;

public class Merge { public static void main(String[] args) {      int [] src=createArray(8);       System.out.println("********归并排序前数组原始数据:");      printArray(src);      System.out.println("********归并排序后:");        int [] tem=sort(src);        printArray(tem);  }

   public static int[] createArray(int size){        //初始化数组       int [] x=new int[size];      for(int i=0;i<x.length;i++){            //创建一个随机对象            Random r=new Random();           x[i]=r.nextInt(100);     }

       return x; } public static void printArray(int [] x){      //如果要打印的数组为null,则不打印       if(x==null){            return ;      }     for(int i=0;i<x.length;i++){            System.out.println(x[i]);     } } public static int[] sort(int [] x){       mergesort(x,0,x.length-1);   return  x;}  public static void  mergesort(int[] x,int left,int right){    if(left<right){        int middle=(left+right)/2;       //对左边进行递归        mergesort(x,left,middle);      //对右边进行递归        mergesort(x,middle+1,right);     //合并      merge(x,left,middle,right);   } } public static void merge(int[] x,int left,int middle,int right){      int [] temArr=new int[x.length];     int mid=middle+1;//右边的起始位置      int tmp=left;        int third=left;      while(left<=middle&&mid<=right){            //从两个数组中选取较小的数放入中间数组            if(x[left]<=x[mid]){              temArr[third++]=x[left++];           }else {               temArr[third++]=x[mid++];            }     }     //将剩余的部分放入中间数组        while(left<=middle){          temArr[third++]=x[left++];       }     while(mid<=right){            temArr[third++]=x[mid++];        }      //将中间数组复制回原数组        while(tmp<=right){            x[tmp]=temArr[tmp++];      }                 }}

直接插入排序 希尔排序 冒泡排序 快速排序 直接选择排序 堆排序 归并排序 基数排序的算法分析和具体实现 ...相关推荐

  1. 数据结构(八):排序 | 插入排序 | 希尔排序 | 冒泡排序 | 快速排序 | 简单选择排序 | 堆排序 | 归并排序 | 基数排序 | 外部排序 | 败者树 | 置换-选择排序 | 最佳归并树

    文章目录 第八章 排序 一.排序的基本概念 (一)什么是排序 (二)排序的应用 (三)排序算法的评价指标 (四)排序算法的分类 (五)总结 二.插入排序 (一)算法思想 (二)算法实现 (三)算法效率 ...

  2. 【排序综合】直接插入排序,希尔排序,快速排序,堆排序,冒泡排序,简单选择排序的简介,实现和算法复杂度分析

    目录 1. 直接插入排序 1.1 直接插入排序简介 1. 什么是直接插入排序 2. 排序思想 1.2 排序实现 1. 排序代码 2. 复杂度分析: 3. 运行结果: 1.3 学习链接 2. 希尔排序( ...

  3. 王道八大排序:直接插入排序 折半插入排序 希尔排序 冒泡排序 快速排序 归并排序 基数排序

    文章目录 1.插入排序 1.1直接插入排序 1.2折半插入排序 1.3希尔排序 2.交换排序 2.1冒泡排序 2.2快速排序 3.选择排序 3.1简单选择排序 3.2堆排序 4.归并排序 5.基数排序 ...

  4. java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序...

    算法是在有限步骤内求解某一问题所使用的一组定义明确的规则.通俗点说,就是计算机解题的过程.在这个过程中,无论是形成解题思路还是编写程序,都是在实施某种算法.前者是推理实现的算法,后者是操作实现的算法. ...

  5. 【排序算法】冒泡排序、简单选择排序、直接插入排序比较和分析

    [排序算法]冒泡排序.简单选择排序.直接插入排序比较和分析 写在前面: 本文简单介绍了冒泡排序.简单选择排序.直接插入排序,并对这三种排序进行比较,入参都是80000个随机数,比较算法耗时.进一步,我 ...

  6. iOS swift 选择排序 冒泡排序 快速排序

    返回上级目录:iOS 算法题 三大经典排序 | 冒泡排序,选择排序,快速排序 - 知乎 文章目录 1.选择排序 2.冒泡排序 3.快速排序 1.选择排序 //选择排序 func rankSelect( ...

  7. 数组中冒泡排序、直接选择排序、反序排序原理与区别

    冒泡排序 冒泡排序是最常用的排序算法之一,它排序的原理是 比较相邻元素的值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把较大的元素移动到数组后面,因为类似水中气泡往上升的动作,所以称作冒泡 ...

  8. 数据结构与算法 第八天常见排序+冒泡排序+快速排序+文件IO+大数据排序+文件合并

    数据结构与算法 第八天常见排序+冒泡排序+快速排序+文件IO+大数据排序+文件合并 第一章 冒泡排序 [1]Bubble_Sort.c 第二章 快速排序 [1]quick_sort.c 第三章 大数据 ...

  9. 冒泡排序算法和选择排序算法比较

      冒泡排序算法详细内容见→冒泡排序算法.   选择排序算法详细内容见→选择排序算法.   冒泡排序算法和选择排序算法的区别: 冒泡排序是比较相邻位置的两个数:而选择排序是按顺序比较,找出最大值或者最 ...

最新文章

  1. 一个完整项目的学习--
  2. python语言入门与精通-Python 为什么入门容易 精通难
  3. 【嵌入式开发】 ARM 关闭 MMU ( 存储体系 | I/D-Cache | MMU | CP15 寄存器 | C1 控制寄存器 | C7 寄存器 | 关闭 MMU )
  4. 磁盘阵列上的文件访问不了--原因是lvm不能activate,解决办法
  5. Otter 异地机房数据同步的demo实施
  6. 实验5:配置通过静态工厂方法创建的bean、实例工厂方法创建的bean、(FactoryBean测试)★
  7. 【千字过程分析】剑指 Offer 04. 二维数组中的查找
  8. python3seek_Python seek()和tell()函数详解
  9. 基于AliOS Things玩转智能语音
  10. Java-所有类型的Class对象
  11. .net Compact Framework 程序设计起步(智能设备的程序设计)
  12. 计算机主机硬件详细介绍,计算机系统的硬件和系统软件详细介绍
  13. sring-list-del-string-int:解析左右编码器的,和#号
  14. 支付宝接口对接指南(四、回调通知对接:websoket方式)【保姆级】
  15. day64 url用法以及django的路由系统
  16. 戴尔电脑插上耳机之后仍然外放
  17. 云南计算机一级c类基础知识,云南省大学计算机一级C类多选题及答案.pdf
  18. pytorch中register_hook以及register_forward_hook
  19. 深度学习笔记(学习中)
  20. 少儿编程Scratch学习教程--Scratch介绍及参赛相关

热门文章

  1. 微信小程序——云函数三方库request-promise的使用详解
  2. excel切片器_听说你还不会用切片器?比筛选好用100倍,小白也能学会
  3. 如何在vscode、remix中结合hardhat编译部署合约
  4. Linux中的阻塞机制
  5. 国内计算机视觉与机器学习研究团队
  6. ENVI中操作出现Error :array dimensions must be greater than 0错误的解决方法
  7. 用pytorch实现神经网络
  8. 网络爬虫:网页信息获取
  9. 【Python】出现SyntaxError: invalid syntax的原因总结
  10. selenium定位到元素后获取其属性_selenium 元素查找与属性