八大排序java源代码

  1. import java.util.Arrays;  
  2.   
  3.   
  4. public class Sort {  
  5.   
  6.     //排序为从小到大序列  
  7.     /** 
  8.      * 冒泡排序:一趟一趟的比较,比较相邻元素的大小,每趟有一个元素沉入最后面的位置 
  9.      * 属于交换类排序 
  10.      * 稳定的排序算法  
  11.      * 平均时间复杂度O(n*n) 
  12.      * 最坏时间复杂度O(n*n) 
  13.      * 空间复杂度O(1) 
  14.      * n较小时适用 
  15.      */  
  16.     public static void bubbleSort(int[] array, int off, int len) {  
  17.         System.out.println("BubbleSort()");  
  18.         for (int i=1; i<len; i++ ) {//第i趟比较  
  19.             boolean isSorted = true;//检测是否有交换  
  20.             for (int j=off; j<off+len-i ; j++){  
  21.                 if (array[j+1]<array[j]){  
  22.                     swap(array, j, j+1);  
  23.                     isSorted = false;//有交换  
  24.                 }  
  25.             }  
  26.             if (isSorted == true)//无交换跳出循环,完成排序   
  27.                 break;  
  28.         }  
  29.     }  
  30.       
  31.     /** 
  32.      * 直接插入排序:每一轮第i个元素跟前面的i-1个元素从后向前比较,一直比较到合适插入的位置 
  33.      * 属于插入类排序 
  34.      * 稳定的排序算法  
  35.      * 平均时间复杂度O(n*n) 
  36.      * 最坏时间复杂度O(n*n) 
  37.      * 空间复杂度O(1) 
  38.      * 大部分有序时适用 
  39.      */  
  40.     public static void insertSort(int[] array, int off, int len) {  
  41.         System.out.println("InsertSort()");  
  42.         int i,j,current;//current记录当前插入元素  
  43.         for (i=off+1; i<off+len; i++) {//array[i]待插入元素,j为比较元素的下标  
  44.             for (j=i-1, current = array[i]; j>=off && array[j]>current; j--) {  
  45.                 array[j+1] = array[j];  
  46.             }  
  47.             array[j+1] = current;  
  48.         }  
  49.     }  
  50.       
  51.     /** 
  52.      * 直接选择排序:第i轮选择剩余最小的元素放入到第i的位置上 
  53.      * 属于选择类排序 
  54.      * 不稳定的排序算法 :如58529第一轮选择交换5和2,破换了原来两个5的顺序 
  55.      * 平均时间复杂度O(n*n) 
  56.      * 最坏时间复杂度O(n*n) 
  57.      * 空间复杂度O(1) 
  58.      * 当n较小时适用 
  59.      */  
  60.     public static void selectSort(int[] array, int off, int len) {  
  61.         for (int i=off; i<off+len-1; i++) {  
  62.             int minIndex = i, min = array[i];//最小元素及下标  
  63.             for(int j=i; j<off+len; j++) {//j为所有待选择元素  
  64.                 if (array[j] < min) {//array[j]更小  
  65.                     min = array[j];  
  66.                     minIndex = j;  
  67.                 }  
  68.             }  
  69.             swap(array, minIndex, i);//选择最小元素放入array[i]  
  70.         }  
  71.     }  
  72.       
  73.     /** 
  74.      * 快速排序:递归算法,将较大的一组换到后面去,较小的一组在前面,前面和后面的分别再递归调用 
  75.      * 属于交换类排序 
  76.      * 不稳定的排序算法 :如35512第一轮时前面的5和后面的2换位置,后面的5和1换位置,位置顺序被破坏 
  77.      * 平均时间复杂度O(n*log2n) 
  78.      * 最坏时间复杂度O(n*n) 
  79.      * 空间复杂度O(1) 
  80.      * n较大 时适用 
  81.      */  
  82.     public static void quickSort(int[] array, int off, int len) {  
  83.         if (len <= 1)  
  84.             return;  
  85.         if (len  == 2)//长度大于三才进行划分  
  86.             if (array[off] > array[off+1]){  
  87.                 swap(array, off, off+1);  
  88.                 return;  
  89.             }  
  90.         int start = off + 1, end = off + len - 1;//交换的开始和结束位置  
  91.         int middleV = array[off];//可以将off和 off+len-1和off+(len-1)/2三个元素中间的赋值  
  92.         while(start < end) {  
  93.             while (array[start] < middleV && start < end)   
  94.                 start++;  
  95.             while (array[end] > middleV && end > start)  
  96.                 end--;  
  97.             if (start < end) {  
  98.                 swap(array, start, end);  
  99.                 start++;  
  100.                 end--;  
  101.             }  
  102.         }  
  103.         int mid = off;  
  104.         if (array[off] > array[end]){  
  105.             swap(array, end, off);    
  106.             mid = end;}  
  107.         quickSort(array, off, mid-off);  
  108.         quickSort(array, mid+1, len-mid+off-1);  
  109.           
  110.     }  
  111.       
  112.     /** 
  113.      * 希尔排序:分组交换的思想,先分组,后交换排序 
  114.      * 属于交换类排序 
  115.      * 不稳定的排序算法 :分组之后交换打破了稳定性 
  116.      * 平均时间复杂度O(n*log2n) 
  117.      * 最坏时间复杂度O(n^s) 1<s<2 
  118.      * 空间复杂度O(1) 
  119.      * n较大时适用 
  120.      */  
  121.     public static void shellSort(int[] array, int off, int len){  
  122.         int d = len / 2;//组内元素的间隔  
  123.         while(d >= 1) {//直到退化到bubble为止  
  124.             shellSortDivision(d,array, off, len);  
  125.             d /= 2;  
  126.         }  
  127.     }  
  128.       
  129.       
  130.     private static void shellSortDivision(int d, int[] array, int off, int len) {  
  131.         // TODO Auto-generated method stub  
  132.         for (int i = 0; i < d ; i++) {//第i个分组  
  133.             for (int j=1; j<=(len-1-i)/d; j++) {//分组内bubble  
  134.                 boolean isSorted = true;  
  135.                 for(int k=off+i; k+d<=off+len-(j-1)*d-1; k+=d){  
  136.                     if (array[k] > array[k+d]) {  
  137.                         swap(array, k, k+d);  
  138.                         isSorted = false;  
  139.                     }  
  140.                 }  
  141.                 if (isSorted == true)  
  142.                     break;  
  143.             }  
  144.         }  
  145.     }  
  146.   
  147.     /** 
  148.      * 归并算法:分而治之的思想 
  149.      * 属于归并类排序 
  150.      * 稳定的排序算法  
  151.      * 平均时间复杂度O(n*log2n) 
  152.      * 最坏时间复杂度O(n*log2n) 
  153.      * 空间复杂度O(n) 
  154.      * n较大时适用 
  155.      */  
  156.     public static void MergeSort(int[] array, int off, int len) {  
  157.         if (len < 2)  
  158.             return;  
  159.         else if (len == 2){  
  160.             if (array[off] > array[off+1])  
  161.                 swap(array, off, off+1);  
  162.             return;  
  163.         }  
  164.         else {  
  165.             int middle = off + (len-1)/2;  
  166.             MergeSort(array, off, middle-off+1);  
  167.             MergeSort(array, middle+1, len-middle+off-1);  
  168.             Merge(array,off,middle,off+len-1);  
  169.         }  
  170.     }  
  171.       
  172.     public static void Merge(int[] array, int left, int middle, int right) {  
  173.         int l = left, r = middle+1, count = 0;  
  174.         int[] newArray = new int[right-left+1];  
  175.         while(l <= middle && r <= right) {  
  176.             if (array[l] < array[r])  
  177.                 newArray[count++] = array[l++];  
  178.             else  
  179.                 newArray[count++] = array[r++];  
  180.         }  
  181.         while (l <= middle)   
  182.             newArray[count++] = array[l++];  
  183.         while (r <= right)  
  184.             newArray[count++] = array[r++];  
  185.         for(int i=left,j=0; i<=right; i++) {  
  186.             array[i] = newArray[j++];  
  187.         }  
  188. //      array = newArray;  
  189.     }  
  190.       
  191.     /** 
  192.      * 堆算法:大根堆a[i] > a[2*i],a[i] > a[2*i+1],先建大根堆,然后不断的:取最大的,调整 
  193.      * 属于选择类排序 
  194.      * 不稳定的排序算法:在调整位置时打破了稳定性  
  195.      * 平均时间复杂度O(n*log2n) 
  196.      * 最坏时间复杂度O(n*log2n) 
  197.      * 空间复杂度O(1) 
  198.      * n较大时适用,选择前i大时适用 
  199.      */  
  200.     public static void heapSort(int[] array, int off, int len) {  
  201.         buildHeap(array,off, len);  
  202.         for (int i = 0;i < len; i++) {  
  203.             swap(array,off,off+len-i-1);//将大根堆最大元素与最后面的位置做交换  
  204.             shiftDown(array, off, len-i-10);//始终调整第一个元素  
  205.         }  
  206.     }  
  207.       
  208.     private static void buildHeap(int[] array, int left, int len) {  
  209.         int pos= len/2 - 1;//从第一个非叶子节点开始    
  210.         for(int i=pos;i>=0;i--)    
  211.         {    
  212.             shiftDown(array,left,len,i); //调整第i个非叶子节点   
  213.         }  
  214.     }  
  215.   
  216.     private static void shiftDown(int[] array, int left, int len, int pos) {  
  217.         // TODO Auto-generated method stub  
  218.         int tmp = array[left+pos];  
  219.         int indexLC = pos*2 + 1, index;//左孩子  
  220.         while(indexLC < len) {//判断孩子是否存在  
  221.             if (indexLC+1 < len && array[left+indexLC]<array[left+indexLC+1])  
  222.                 index = indexLC + 1;//右孩子大  
  223.             else  
  224.                 index = indexLC;//左孩子大  
  225.             if(tmp < array[left+index]) {//交换  
  226.                 array[left+pos] = array[left+index];  
  227.                 pos = index;//交换后大值继续跟孩子比较  
  228.                 indexLC = pos*2 + 1;  
  229.             }else break;  
  230.         }  
  231.         array[left+pos] = tmp;//跟目标交换完成  
  232.     }  
  233.   
  234.     /** 
  235.      * 基数排序 
  236.      * 稳定的排序算法  
  237.      * 最差时间复杂度是 O(k·n) 
  238.      * 空间复杂度O(k·n) 
  239.      * 多个刻度指标时适用 
  240.      * @param array  
  241.      * @param radix 基数 
  242.      * @param distance 几遍 
  243.      */  
  244.      private static void radixSort(int[] array,int radix, int distance) {    
  245.             //array为待排序数组    
  246.             //radix,代表基数    
  247.             //代表排序元素的位数    
  248.                 
  249.             int length = array.length;    
  250.             int[] temp = new int[length];//用于暂存元素    
  251.             int[] count = new int[radix];//用于统计基数内元素个数    
  252.             int divide = 1;    
  253.                 
  254.             for (int i = 0; i < distance; i++) {    
  255.                     
  256.                 System.arraycopy(array, 0,temp, 0, length);    
  257.                 Arrays.fill(count, 0);    
  258.                     
  259.                 for (int j = 0; j < length; j++) {    
  260.                     int tempKey = (temp[j]/divide)%radix;    
  261.                     count[tempKey]++;  //基数选中计数  
  262.                 }    
  263.                     
  264.                 for (int j = 1; j < radix; j++) {    
  265.                     count [j] = count[j] + count[j-1];//累计计数    
  266.                 }    
  267.                 for (int j = length - 1; j >= 0; j--) {    
  268.                     int tempKey = (temp[j]/divide)%radix;    
  269.                     count[tempKey]--;//从后往前赋值    
  270.                     array[count[tempKey]] = temp[j];    
  271.                 }    
  272.                     
  273.                 divide = divide * radix;                    
  274.                     
  275.             }    
  276.                         
  277.         }    
  278.       
  279.     //交换两个元素  
  280.     private static void swap(int[] array, int a, int b) {  
  281.         int t = array[a];  
  282.         array[a] = array[b];  
  283.         array[b] = t;  
  284.         }  
  285.       
  286.     //打印数组  
  287.     private static void printArray(String s, int[] array, int off, int len) {  
  288.         System.out.print(s);  
  289.         for(int i=off; i<off+len; i++) {  
  290.             if (i == off)  
  291.                 System.out.print("[" + array[i] + ",");  
  292.             else if (i == off+len-1)  
  293.                 System.out.print(array[i]);  
  294.             else   
  295.                 System.out.print(array[i] + ",");  
  296.         }  
  297.         System.out.println("]");  
  298.     }  
  299.       
  300.     private static int getMiddleIndexOfThreeElement(int[] array,int a, int b, int c) {  
  301.         if (array[a] < array[b]) {  
  302.             if (array[b] < array[c])  
  303.                 return b;  
  304.             else if (array[c] < array[a])  
  305.                     return a;  
  306.             else return c;  
  307.         }else {  
  308.             if (array[a] < array[c])  
  309.                 return a;  
  310.             else if (array[c] < array[b])  
  311.                     return b;  
  312.             else return c;  
  313.         }  
  314.     }  
  315.   
  316.   
  317.     public static int getMiddle(int[] list, int low, int high) {    
  318.                 int tmp = list[low];    //数组的第一个作为中轴    
  319.              while (low < high) {    
  320.                  while (low < high && list[high] > tmp) {    
  321.                          high--;    
  322.                  }    
  323.                 list[low] = list[high];//比中轴小的记录移到低端    
  324.                 while (low < high && list[low] <= tmp) {    
  325.                         low++;    
  326.                }    
  327.                list[high] = list[low];   //比中轴大的记录移到高端   
  328.                 
  329.              }    
  330.                 list[low] = tmp;              //中轴记录到尾    
  331.                 return low;                   //返回中轴的位置    
  332.       }    
  333.   
  334.     public static void quickSort2(int[] array, int low, int high) {    
  335.                 if (low < high) {    
  336.                  int middle = getMiddle(array, low, high);  //将list数组进行一分为二    
  337.                  quickSort2(array, low, middle - 1);        //对低字表进行递归排序    
  338.            quickSort2(array, middle + 1, high);       //对高字表进行递归排序    
  339.                  }    
  340.      }   
[java]  view plain copy
  1.       
  2.     /** 
  3.      * @param args 
  4.      */  
  5.     public static void main(String[] args) {  
  6.         // TODO Auto-generated method stub  
  7.         int[] array =  {5,7,8,5,21,5,7,1,23,53,6,47,7,2,4,74,7};  
  8.         printArray("排序前:", array, 0, array.length);  
  9.         Sort.heapSort(array, 0, array.length);  
  10.         printArray("排序后:", array, 0, array.length);  
  11.     }  
  12.   
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值