JAVA排序汇总

Java代码 复制代码
  1. package com.softeem.jbs.lesson4;   
  2.     
  3. import java.util.Random;   
  4.     
  5. /**  
  6.  * 排序测试类  
  7.  *  
  8.  * 排序算法的分类如下:  
  9.  * 1.插入排序(直接插入排序、折半插入排序、希尔排序);  
  10.  * 2.交换排序(冒泡泡排序、快速排序);  
  11.  * 3.选择排序(直接选择排序、堆排序);  
  12.  * 4.归并排序;  
  13.  * 5.基数排序。  
  14.  *  
  15.  * 关于排序方法的选择:  
  16.  * (1)若n较小(如n≤50),可采用直接插入或直接选择排序。  
  17.  *  当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插人,应选直接选择排序为宜。  
  18.  * (2)若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜;  
  19.  * (3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。  
  20.  *  
  21.  */  
  22. public class SortTest {   
  23.     
  24.        /**  
  25.         * 初始化测试数组的方法  
  26.         * @return 一个初始化好的数组  
  27.         */  
  28.        public int[] createArray() {   
  29.               Random random = new Random();   
  30.               int[] array = new int[10];   
  31.               for (int i = 0; i < 10; i++) {   
  32.                      array[i] = random.nextInt(100) - random.nextInt(100);//生成两个随机数相减,保证生成的数中有负数   
  33.               }   
  34.               System.out.println("==========原始序列==========");   
  35.               printArray(array);   
  36.               return array;   
  37.        }   
  38.     
  39.        /**  
  40.         * 打印数组中的元素到控制台  
  41.         * @param source  
  42.         */  
  43.        public void printArray(int[] data) {   
  44.               for (int i : data) {   
  45.                      System.out.print(i + " ");   
  46.               }   
  47.               System.out.println();   
  48.        }   
  49.     
  50.        /**  
  51.         * 交换数组中指定的两元素的位置  
  52.         * @param data  
  53.         * @param x  
  54.         * @param y  
  55.         */  
  56.        private void swap(int[] data, int x, int y) {   
  57.               int temp = data[x];   
  58.               data[x] = data[y];   
  59.               data[y] = temp;   
  60.        }   
  61.     
  62.        /**  
  63.         * 冒泡排序----交换排序的一种  
  64.         * 方法:相邻两元素进行比较,如有需要则进行交换,每完成一次循环就将最大元素排在最后(如从小到大排序),下一次循环是将其他的数进行类似操作。  
  65.         * 性能:比较次数O(n^2),n^2/2;交换次数O(n^2),n^2/4  
  66.         *  
  67.         * @param data 要排序的数组  
  68.         * @param sortType 排序类型  
  69.         * @return  
  70.         */  
  71.        public void bubbleSort(int[] data, String sortType) {   
  72.               if (sortType.equals("asc")) { //正排序,从小排到大   
  73.                      //比较的轮数   
  74.                      for (int i = 1; i < data.length; i++) {   
  75.                             //将相邻两个数进行比较,较大的数往后冒泡   
  76.                             for (int j = 0; j < data.length - i; j++) {   
  77.                                    if (data[j] > data[j + 1]) {   
  78.                                           //交换相邻两个数   
  79.                                           swap(data, j, j + 1);   
  80.                                    }   
  81.                             }   
  82.                      }   
  83.               } else if (sortType.equals("desc")) { //倒排序,从大排到小   
  84.                      //比较的轮数   
  85.                      for (int i = 1; i < data.length; i++) {   
  86.                             //将相邻两个数进行比较,较大的数往后冒泡   
  87.                             for (int j = 0; j < data.length - i; j++) {   
  88.                                    if (data[j] < data[j + 1]) {   
  89.                                           //交换相邻两个数   
  90.                                           swap(data, j, j + 1);   
  91.                                    }   
  92.                             }   
  93.                      }   
  94.               } else {   
  95.                      System.out.println("您输入的排序类型错误!");   
  96.               }   
  97.               printArray(data);//输出冒泡排序后的数组值   
  98.        }   
  99.     
  100.        /**  
  101.         * 直接选择排序法----选择排序的一种  
  102.         * 方法:每一趟从待排序的数据元素中选出最小(或最大)的一个元素, 顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。  
  103.         * 性能:比较次数O(n^2),n^2/2  
  104.         *       交换次数O(n),n  
  105.         *       交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CUP时间多,所以选择排序比冒泡排序快。  
  106.         *       但是N比较大时,比较所需的CPU时间占主要地位,所以这时的性能和冒泡排序差不太多,但毫无疑问肯定要快些。  
  107.         *  
  108.         * @param data 要排序的数组  
  109.         * @param sortType 排序类型  
  110.         * @return  
  111.         */  
  112.        public void selectSort(int[] data, String sortType) {   
  113.     
  114.               if (sortType.equals("asc")) { //正排序,从小排到大   
  115.                      int index;   
  116.                      for (int i = 1; i < data.length; i++) {   
  117.                             index = 0;   
  118.                             for (int j = 1; j <= data.length - i; j++) {   
  119.                                    if (data[j] > data[index]) {   
  120.                                           index = j;   
  121.     
  122.                                    }   
  123.                             }   
  124.                             //交换在位置data.length-i和index(最大值)两个数   
  125.                             swap(data, data.length - i, index);   
  126.                      }   
  127.               } else if (sortType.equals("desc")) { //倒排序,从大排到小   
  128.                      int index;   
  129.                      for (int i = 1; i < data.length; i++) {   
  130.                             index = 0;   
  131.                             for (int j = 1; j <= data.length - i; j++) {   
  132.                                    if (data[j] < data[index]) {   
  133.                                           index = j;   
  134.     
  135.                                    }   
  136.                             }   
  137.                             //交换在位置data.length-i和index(最大值)两个数   
  138.                             swap(data, data.length - i, index);   
  139.                      }   
  140.               } else {   
  141.                      System.out.println("您输入的排序类型错误!");   
  142.               }   
  143.               printArray(data);//输出直接选择排序后的数组值   
  144.        }   
  145.     
  146.        /**  
  147.         * 插入排序  
  148.         * 方法:将一个记录插入到已排好序的有序表(有可能是空表)中,从而得到一个新的记录数增1的有序表。  
  149.         * 性能:比较次数O(n^2),n^2/4  
  150.         *       复制次数O(n),n^2/4  
  151.         *       比较次数是前两者的一般,而复制所需的CPU时间较交换少,所以性能上比冒泡排序提高一倍多,而比选择排序也要快。  
  152.         *  
  153.         * @param data 要排序的数组  
  154.         * @param sortType 排序类型  
  155.         */  
  156.        public void insertSort(int[] data, String sortType) {   
  157.               if (sortType.equals("asc")) { //正排序,从小排到大   
  158.                      //比较的轮数   
  159.                      for (int i = 1; i < data.length; i++) {   
  160.                             //保证前i+1个数排好序   
  161.                             for (int j = 0; j < i; j++) {   
  162.                                    if (data[j] > data[i]) {   
  163.                                           //交换在位置j和i两个数   
  164.                                           swap(data, i, j);   
  165.                                    }   
  166.                             }   
  167.                      }   
  168.               } else if (sortType.equals("desc")) { //倒排序,从大排到小   
  169.                      //比较的轮数   
  170.                      for (int i = 1; i < data.length; i++) {   
  171.                             //保证前i+1个数排好序   
  172.                             for (int j = 0; j < i; j++) {   
  173.                                    if (data[j] < data[i]) {   
  174.                                           //交换在位置j和i两个数   
  175.                                           swap(data, i, j);   
  176.                                    }   
  177.                             }   
  178.                      }   
  179.               } else {   
  180.                      System.out.println("您输入的排序类型错误!");   
  181.               }   
  182.               printArray(data);//输出插入排序后的数组值   
  183.        }   
  184.     
  185.        /**  
  186.         * 反转数组的方法  
  187.         * @param data 源数组  
  188.         */  
  189.        public void reverse(int[] data) {   
  190.     
  191.               int length = data.length;   
  192.               int temp = 0;//临时变量   
  193.     
  194.               for (int i = 0; i < length / 2; i++) {   
  195.                      temp = data[i];   
  196.                      data[i] = data[length - 1 - i];   
  197.                      data[length - 1 - i] = temp;   
  198.               }   
  199.               printArray(data);//输出到转后数组的值   
  200.        }   
  201.     
  202.        /**  
  203.         * 快速排序  
  204.         * 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。  
  205.         * 步骤为:  
  206.         * 1. 从数列中挑出一个元素,称为 "基准"(pivot),  
  207.         * 2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分割之后,该基准是它的最后位置。这个称为分割(partition)操作。  
  208.         * 3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。  
  209.         * 递回的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递回下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。  
  210.         * @param data 待排序的数组  
  211.         * @param low  
  212.         * @param high  
  213.         * @see SortTest#qsort(int[], int, int)  
  214.         * @see SortTest#qsort_desc(int[], int, int)  
  215.         */  
  216.        public void quickSort(int[] data, String sortType) {   
  217.               if (sortType.equals("asc")) { //正排序,从小排到大   
  218.                      qsort_asc(data, 0, data.length - 1);   
  219.               } else if (sortType.equals("desc")) { //倒排序,从大排到小   
  220.                      qsort_desc(data, 0, data.length - 1);   
  221.               } else {   
  222.                      System.out.println("您输入的排序类型错误!");   
  223.               }   
  224.        }   
  225.     
  226.        /**  
  227.         * 快速排序的具体实现,排正序  
  228.         * @param data  
  229.         * @param low  
  230.         * @param high  
  231.         */  
  232.        private void qsort_asc(int data[], int low, int high) {   
  233.               int i, j, x;   
  234.               if (low < high) { //这个条件用来结束递归   
  235.                      i = low;   
  236.                      j = high;   
  237.                      x = data[i];   
  238.                      while (i < j) {   
  239.                             while (i < j && data[j] > x) {   
  240.                                    j--; //从右向左找第一个小于x的数   
  241.                             }   
  242.                             if (i < j) {   
  243.                                    data[i] = data[j];   
  244.                                    i++;   
  245.                             }   
  246.                             while (i < j && data[i] < x) {   
  247.                                    i++; //从左向右找第一个大于x的数   
  248.                             }   
  249.                             if (i < j) {   
  250.                                    data[j] = data[i];   
  251.                                    j--;   
  252.                             }   
  253.                      }   
  254.                      data[i] = x;   
  255.                      qsort_asc(data, low, i - 1);   
  256.                      qsort_asc(data, i + 1, high);   
  257.               }   
  258.        }   
  259.     
  260.        /**  
  261.         * 快速排序的具体实现,排倒序  
  262.         * @param data  
  263.         * @param low  
  264.         * @param high  
  265.         */  
  266.        private void qsort_desc(int data[], int low, int high) {   
  267.               int i, j, x;   
  268.               if (low < high) { //这个条件用来结束递归   
  269.                      i = low;   
  270.                      j = high;   
  271.                      x = data[i];   
  272.                      while (i < j) {   
  273.                             while (i < j && data[j] < x) {   
  274.                                    j--; //从右向左找第一个小于x的数   
  275.                             }   
  276.                             if (i < j) {   
  277.                                    data[i] = data[j];   
  278.                                    i++;   
  279.                             }   
  280.                             while (i < j && data[i] > x) {   
  281.                                    i++; //从左向右找第一个大于x的数   
  282.                             }   
  283.                             if (i < j) {   
  284.                                    data[j] = data[i];   
  285.                                    j--;   
  286.                             }   
  287.                      }   
  288.                      data[i] = x;   
  289.                      qsort_desc(data, low, i - 1);   
  290.                      qsort_desc(data, i + 1, high);   
  291.               }   
  292.        }   
  293.     
  294.        /**  
  295.         *二分查找特定整数在整型数组中的位置(递归)  
  296.         *查找线性表必须是有序列表  
  297.         *@paramdataset  
  298.         *@paramdata  
  299.         *@parambeginIndex  
  300.         *@paramendIndex  
  301.         *@returnindex  
  302.         */  
  303.        public int binarySearch(int[] dataset, int data, int beginIndex,   
  304.                      int endIndex) {   
  305.               int midIndex = (beginIndex + endIndex) >>> 1//相当于mid = (low + high) / 2,但是效率会高些   
  306.               if (data < dataset[beginIndex] || data > dataset[endIndex]   
  307.                             || beginIndex > endIndex)   
  308.                      return -1;   
  309.               if (data < dataset[midIndex]) {   
  310.                      return binarySearch(dataset, data, beginIndex, midIndex - 1);   
  311.               } else if (data > dataset[midIndex]) {   
  312.                      return binarySearch(dataset, data, midIndex + 1, endIndex);   
  313.               } else {   
  314.                      return midIndex;   
  315.               }   
  316.        }   
  317.     
  318.        /**  
  319.         *二分查找特定整数在整型数组中的位置(非递归)  
  320.         *查找线性表必须是有序列表  
  321.         *@paramdataset  
  322.         *@paramdata  
  323.         *@returnindex  
  324.         */  
  325.        public int binarySearch(int[] dataset, int data) {   
  326.               int beginIndex = 0;   
  327.               int endIndex = dataset.length - 1;   
  328.               int midIndex = -1;   
  329.               if (data < dataset[beginIndex] || data > dataset[endIndex]   
  330.                             || beginIndex > endIndex)   
  331.                      return -1;   
  332.               while (beginIndex <= endIndex) {   
  333.                      midIndex = (beginIndex + endIndex) >>> 1//相当于midIndex = (beginIndex + endIndex) / 2,但是效率会高些   
  334.                      if (data < dataset[midIndex]) {   
  335.                             endIndex = midIndex - 1;   
  336.                      } else if (data > dataset[midIndex]) {   
  337.                             beginIndex = midIndex + 1;   
  338.                      } else {   
  339.                             return midIndex;   
  340.                      }   
  341.               }   
  342.               return -1;   
  343.        }   
  344.     
  345.        public static void main(String[] args) {   
  346.               SortTest sortTest = new SortTest();   
  347.     
  348.               int[] array = sortTest.createArray();   
  349.     
  350.               System.out.println("==========冒泡排序后(正序)==========");   
  351.               sortTest.bubbleSort(array, "asc");   
  352.               System.out.println("==========冒泡排序后(倒序)==========");   
  353.               sortTest.bubbleSort(array, "desc");   
  354.     
  355.               array = sortTest.createArray();   
  356.     
  357.               System.out.println("==========倒转数组后==========");   
  358.               sortTest.reverse(array);   
  359.     
  360.               array = sortTest.createArray();   
  361.     
  362.               System.out.println("==========选择排序后(正序)==========");   
  363.               sortTest.selectSort(array, "asc");   
  364.               System.out.println("==========选择排序后(倒序)==========");   
  365.               sortTest.selectSort(array, "desc");   
  366.     
  367.               array = sortTest.createArray();   
  368.     
  369.               System.out.println("==========插入排序后(正序)==========");   
  370.               sortTest.insertSort(array, "asc");   
  371.               System.out.println("==========插入排序后(倒序)==========");   
  372.               sortTest.insertSort(array, "desc");   
  373.     
  374.               array = sortTest.createArray();   
  375.               System.out.println("==========快速排序后(正序)==========");   
  376.               sortTest.quickSort(array, "asc");   
  377.               sortTest.printArray(array);   
  378.               System.out.println("==========快速排序后(倒序)==========");   
  379.               sortTest.quickSort(array, "desc");   
  380.               sortTest.printArray(array);   
  381.     
  382.               System.out.println("==========数组二分查找==========");   
  383.               System.out.println("您要找的数在第
分享到:
评论

你可能感兴趣的:(java,算法,J#)