zoukankan      html  css  js  c++  java
  • 8大排序算法的java实现--做个人收藏

          排序算法分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因为数据量太大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。这里只讨论内部排序,常见的内部排序算法有:插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序、及基数排序。

    1、插入排序

    插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序的数据,在已排序序列中从后往前扫描,找到相应位置并插入。算法步骤如下:

    • 将第一个待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成未排序序列;
    • 从头到尾一次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置,即满足有序的顺序,若相等,则插入到这个相等元素的后面。

    插入排序java代码:

     1 public class InsertSort {
     2     public static void insertSort(int []data){
     3         for(int i=0;i<data.length-1;i++){
     4             int temp=data[i+1];
     5             int j=i;
     6             while(j>-1&&data[j]>temp){
     7                 data[j+1]=data[j];
     8                 j--;
     9             }
    10             data[j+1]=temp;
    11         }
    12     }
    13     public static void main(String[] args) {
    14         // TODO Auto-generated method stub
    15         int data[]=new int[]{12,5,44,11,50,9};
    16         insertSort(data);
    17         for(int i:data){
    18             System.out.println(i);
    19         }
    20     }
    21 
    22 }

    2、希尔排序

    希尔排序也称为递减增量排序算法,是插入排序的一种改进,其思想是:先将整个待排序的序列分割成若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。算法步骤如下:

    • 选择一个增量序列t1,t2,...,tk,其中ti>tj,tk=1;
    • 增量序列个数为k,对序列进行k趟插入排序;
    • 每趟排序,根据对应的增量ti,将待排序序列分割成若干长度为m得子序列,然后对各子序列进行直接插入排序,当ti为1时,是对“基本有序”的整个序列排序。

     希尔排序实现:

     1 public class SellSort {
     2     public static void sellSort(int []data){
     3         int []step=new int[]{6,3,1};
     4         int i,j,k;
     5         for(int s:step){
     6             for(i=0;i<s;i++){
     7                 for(j=i;j<data.length-s;j+=s){
     8                     k=j;
     9                     int temp=data[j+s];
    10                     while(k>-1&&data[k]>temp){
    11                         data[k+s]=data[k];
    12                         k-=s;
    13                     }
    14                     data[k+s]=temp;
    15                 }
    16             }
    17         }
    18     }
    19     public static void main(String[] args) {
    20         // TODO Auto-generated method stub
    21         int []data=new int[]{12,5,44,11,50,9,23,32};
    22         sellSort(data);
    23         for(int i:data){
    24             System.out.println(i);
    25         }
    26     }
    27 
    28 }

    3、选择排序

     选择排序是一种简单直观的排序算法,基本思想是:对待排序序列进行扫描,每次找到最小(大)的元素,然后和未排序序列的首元素进行交换,直到所有的待排序序列都是有序的为止。算法步骤如下:

    • 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置;
    • 再从剩余未排序序列中继续寻找最小(大)元素,然后放到已排序序列的末尾;
    • 重复第二步,直到所有元素排序完毕。

     选择排序实现代码:

     1 public class SelectSort {
     2 
     3     public static void selectSort(int []data){
     4         for(int i=0;i<data.length;i++){
     5             int minIndex=i;//每次记录值最小的下标
     6             int temp;
     7             for(int j=i+1;j<data.length;j++){
     8                 if(data[j]<data[minIndex]) minIndex=j;
     9             }
    10             temp=data[i];
    11             data[i]=data[minIndex];
    12             data[minIndex]=temp;
    13         }
    14     }
    15     public static void main(String[] args) {
    16         // TODO Auto-generated method stub
    17         int []data=new int[]{12,5,44,11,50,9};
    18         selectSort(data);
    19         for(int i:data){
    20             System.out.println(i);
    21         }
    22     }
    23 
    24 }

    4、堆排序

     堆排序是利用堆这种数据结构所设计的一种排序算法。这个堆所满足的性质是:子结点的键值总是不小于(不大于)它的父结点。算法基本步骤如下:

    • 把未排序序列创建成为一个堆;
    • 把堆首(为最大(小)值)和堆尾互换;
    • 堆的规模减1,调整堆;
    • 重复,直到所有元素排序完成。

     堆排序实现:

     1 public class HeapSort {
     2     //初始化数组为最大堆
     3     private static void initCreateHeap(int []data){
     4         for(int i=data.length/2-1;i>=0;i--){
     5             adjHeap(data,data.length,i);
     6         }
     7     }
     8     //调整结点data[h],使之满足最大堆,n为data中剩余未排序的元素的个数
     9     private static void adjHeap(int []data,int n,int h){
    10         int i=h;
    11         int l=2*i+1;
    12         int temp=data[i];
    13         boolean flag=true;
    14         while(l<n&&flag){
    15             if(l+1<n&&data[l]<data[l+1]) l++;
    16             if(temp>data[l]){
    17                 flag=false;
    18             }else{
    19                 data[i]=data[l];
    20                 data[l]=temp;
    21                 i=l;
    22                 l=2*i+1;
    23             }
    24         }
    25     }
    26     public static void heapSort(int []data){
    27         initCreateHeap(data);
    28         for(int i=data.length-1;i>0;i--){
    29             int temp=data[i];
    30             data[i]=data[0];
    31             data[0]=temp;
    32             adjHeap(data,i,0);
    33         }
    34     }
    35     public static void main(String[] args) {
    36         // TODO Auto-generated method stub
    37         int []data=new int[]{12,5,44,11,50,9,23,32};
    38         heapSort(data);
    39         for(int i:data){
    40             System.out.println(i);
    41         }
    42     }
    43 
    44 }

    5、冒泡排序

     冒泡排序的基本思想是遍历未排序序列,把相邻的元素调整为有序,这样每次都会有最大(小)的元素出现在未排序序列的末尾,就跟冒泡泡一样,把这些元素有序地排出来了。算法步骤:

    • 比较相邻的元素。如果不满足有序序列,就交换它们;
    • 对每一对相邻元素都做同样的工作,从头到尾,最后末尾元素会是最大的数;
    • 未排序的元素个数减1,重复以上工作。

     算法实现代码:

     1 public class BubbleSort {
     2     public static void bubbleSort(int []data){
     3         boolean flag=false;//标志位,如果有序可以提前结束循环
     4         for(int i=0;i<data.length;i++){
     5             if(flag) break;
     6             flag=true;
     7             for(int j=0;j<data.length-1-i;j++){
     8                 if(data[j]>data[j+1]){
     9                     int temp=data[j];
    10                     data[j]=data[j+1];
    11                     data[j+1]=temp;
    12                     flag=false;
    13                 }
    14             }
    15         }
    16     }
    17     public static void main(String[] args) {
    18         // TODO Auto-generated method stub
    19         int []data=new int[]{12,5,44,11,50,9};
    20         bubbleSort(data);
    21         for(int i:data){
    22             System.out.println(i);
    23         }
    24     }
    25 
    26 }

    6、快速排序

     快速排序的算法使用分治的策略来进行排序的,对于按从小到大的排序具体的实现步骤如下:

    • 从数据序列中选出一个元素当基准
    • 把比基准小的所有元素放到基准之前,把所有比基准大的元素放到基准之后,这样就把序列划分为以基准为分界的两个分区,基准之前分区的所有元素都比基准小,基准之后的分区的所有元素都比基准大;
    • 两个分区递归的重复以上步骤,直到分区的元素个数小于1。

     快速排序实现;

     1 public class QuickSort {
     2     public static void quickSort(int []data,int s,int e){
     3         int i=s,j=e;
     4         int temp=data[s];
     5         while(i<j){
     6             while(i<j){
     7                 if(data[j]<temp) {
     8                     data[i]=data[j];
     9                     i++;
    10                     break;
    11                 }
    12                 j--;
    13             }
    14             while(i<j){
    15                 if(data[i]>temp) {
    16                     data[j]=data[i];
    17                     j--;
    18                     break;
    19                     }
    20                 i++;
    21                 }
    22         }
    23         data[i]=temp;
    24         if(s<i)quickSort(data,s,i-1);
    25         if(j<e)quickSort(data,j+1,e);
    26     }
    27     public static void main(String[] args) {
    28         // TODO Auto-generated method stub
    29         int []data=new int[]{12,5,44,11,50,9};
    30         quickSort(data,0,data.length-1);
    31         for(int i:data){
    32             System.out.println(i);
    33         }
    34     }
    35 
    36 }

    7、归并排序

    归并排序是建立在归并操作上的一种有效的排序算法,也在采用分治的策略,算法步骤如下;

    • 申请空间,使其大小为两个有序序列的和,该空间用来存放合并后的序列;
    • 设定指针分别指向有序序列的起始位置;
    • 比较两个指针所指向的元素,选择适当的加入合并空间,并移动指针;
    • 重复第3步,直到某一指针到达序列尾;
    • 将另一序列剩下的元素直接复制到合并序列末尾。

     归并算法实现代码:

     1 public class MergeSort {
     2     //一次归并,k为归并子数组的长度,temp保存归并的中间结果
     3     private static void merge(int []data,int []temp,int k){
     4         int l1=0,l2,u1,u2;
     5         int n=data.length;
     6         int i,j,m=0;
     7         
     8         while(l1+k<=n-1){
     9             u1=l1+k-1;
    10             l2=u1+1;
    11             u2=(l2+k>n)?n-1:l2+k-1;
    12             
    13             for(i=l1,j=l2;i<=u1&&j<=u2;){
    14                 if(data[i]<data[j]){
    15                     temp[m++]=data[i++];
    16                 }else{
    17                     temp[m++]=data[j++];
    18                 }
    19             }
    20             //若子数组1还有剩余的数据,则直接加入temp数组
    21             while(i<=u1){
    22                 temp[m++]=data[i++];
    23             }
    24             //若子数组2还有剩余的数据,则直接加入temp数组
    25             while(j<=u2){
    26                 temp[m++]=data[j++];
    27             }
    28             l1=u2+1;
    29         }
    30         //将剩余的只够一组的数据加进来
    31         for(i=l1;i<n;){
    32             temp[m++]=data[i++];
    33         }
    34         
    35     }
    36     public static void mergeSort(int []data){
    37         int []temp=new int[data.length];
    38         int k=1;
    39         while(k<data.length){
    40             merge(data,temp,k);
    41             for(int j=0;j<data.length;j++) data[j]=temp[j];
    42             k*=2;
    43         }
    44         
    45     }
    46     public static void main(String[] args) {
    47         // TODO Auto-generated method stub
    48         int []data=new int[]{12,5,44,11,50,9,23,32,27};
    49         mergeSort(data);
    50         for(int i:data){
    51             System.out.println(i);
    52         }
    53     }
    54 
    55 }

    8、基数排序

     基数排序也叫做桶排序,是一种非比较型的整数排序算法,基本思想是将整数按位切割成不同的数字,然后放到不同的桶里面,然后根据桶的规则有序输出。实现步骤如下:

    • 初始化d个桶,d为序列中数字的进制;
    • 按照关键字最低位数值依次放入桶中,然后分别按照桶号顺序元素进桶先后次序收集数据元素,这样就得到一个新的排列,这个过程称为一次基数排序;
    • 然后分别按照次地位直到最高位的顺序进行一次基数排序,进行m次基数排序后就会得到有序序列,这里的m是整数序列的最高位数。

     基数排序代码:

     1 public class RadixSort {
     2     private static void radixSort(int []data,int m,int d){
     3         int i,j,k,power=1;
     4         int n=data.length;
     5         Queue []q=new LinkedList[d];
     6         
     7         //初始化队列数组
     8         for(i=0;i<d;i++){
     9             q[i]=new LinkedList();
    10         }
    11         //进行m次桶排序
    12         for(i=0;i<m;i++){
    13             for(j=0;j<n;j++){
    14                 k=data[j]/power-(data[j]/(power*d))*d;//取得每个数第i位的值
    15                 q[k].add(data[j]);
    16             }
    17             for(k=0,j=0;j<d;j++){
    18                 while(!q[j].isEmpty()){
    19                     data[k++]=(Integer)q[j].remove();
    20                 }
    21             }
    22             power*=d;
    23         }
    24     }
    25 
    26     public static void main(String[] args) {
    27         // TODO Auto-generated method stub
    28         int []data=new int[]{710,841,342,45,686,6,429,134,68,264};
    29         int m=3,d=10;//关键字是m位d进制的
    30         radixSort(data,m,d);
    31         for(int i:data){
    32             System.out.println(i);
    33         }
    34     }
    35 
    36 }

    ================================================================================================================================================

    以上排序算法归纳:

  • 相关阅读:
    Ubuntu下虚拟机卡顿
    C函数重载
    ACPI电源状态定义
    /dev/random生成随机数慢的问题
    GCC强制静态库链接未使用的函数、变量
    cmake交叉编译问题
    cmake语法
    CentOS安装OpenOCD
    LOJ3119. 「CTS2019 | CTSC2019」随机立方体 二项式反演
    BZOJ4710 [Jsoi2011]分特产 容斥
  • 原文地址:https://www.cnblogs.com/harderman-mapleleaves/p/4533167.html
Copyright © 2011-2022 走看看