zoukankan      html  css  js  c++  java
  • 一天一个Java基础——排序

    插入排序


    直接插入排序:

        当插入第i个数据元素k时,由前i-1个数据元素组成已排序的数据序列,将k与数据序列中各数据元素依次进行比较后,插入到数据序列的适当位置,使得插入后的数据序列仍是排序的。

        直接插入排序算法是稳定的,时间复杂度为O(n^2)。 

     1 /*
     2  * 插入排序
     3  *     1.外层循环(循环控制变量i)的迭代是为了获取已排好序的子数列
     4  *     2.内层循环(循环控制变量k)将list[i]插入到从list[0]到list[i-1]的子数列中
     5  */
     6 public static void insertionSort(int[] array) {
     7     for (int i = 1; i < array.length; i++) {
     8         int minValue = array[i];
     9         int k;
    10         for (k = i - 1;k >= 0 && minValue < array[k]; k--) {
    11             array[k + 1] = array[k];
    12         }
    13         array[k + 1] = minValue;
    14     }
    15 }

    希尔排序:

        排序之初,允许数据元素做较大的移动,而当数据元素接近目的地时,再做较小的移动。这样做可使排序过程加快。希尔排序的算法思想非常简单,但如何选择增量以产生最好的排序效果,至今仍没定论。

        希尔排序算法是不定的,所需的时间取决于每次排序时增量的个数和增量的取值,若增量的取值比较合理,希尔排序算法的时间复杂度约为O(n(log_2n)^2)。

    交换排序


    冒泡排序:

        将相邻的两个数据元素按关键字进行比较,如果反序,则交换。对于一个待排序的数据序列,经一趟排序后,最大值数据元素移到最后位置,其它值较大的数据元素也向最终位置移动,此过程称为一趟起泡。

        冒泡排序算法是稳定的,时间复杂度为O(n^2)。

    快速排序:

        快速排序是目前平均性能较好的一种排序算法。

        在待排序的数据序列中任意选择一个值作为基准值,由序列的两端交替地向中间进行比较、交换,使得所有比基准值晓得元素都处于序列的左端,比基准值大的元素都处于序列的右端,这样序列就被划分成两个子序列。再对两个子序列分别进行同样的操作,直到子序列的长度为1时,则已排好序。每趟排序完,作为基准值的数据元素需要找到它在排好序的序列中的最终位置。

    选择排序:

      设待排序的数据序列有n个元素,第1趟排序,比较n个元素,选择关键字最小的元素,将其交换到序列的第1个位置上;第2趟排序,在余下的n-1个元素中,再选取关键字最小的元素,交换到序列的第2个位置上.....经过n-1趟排序,n个元素的数据序列则按递增次序排序完成。

      直接选择排序算法是不稳定的

     1 /*
     2  * 选择排序
     3  *     1.选择排序法先找到数列中最小的数
     4  *     2.然后将它放在数列的最前面
     5  *     3.在剩下的数中,循环1、2操作
     6  */
     7 public static void selectionSort(int[] array) {
     8     for (int i = 0; i < array.length - 1; i++) {
     9         int minValue = array[i];
    10         int minIndex = i;
    11         for (int j = i + 1;j < array.length;j++) {
    12             if (array[j] < minValue) {
    13                 minValue = array[j];
    14                 minIndex = j;
    15             }
    16         }
    17         if (minIndex != i) {
    18             array[minIndex] = array[i];
    19             array[i] = minValue;
    20         }
    21     }
    22 }

    归并排序: 

      归并排序算法可以递归地描述为:算法将数组分为两半,对每部分递归地应用归并排序。在两部分都排好序后,对它们进行归并。

      递归调用持续将数组划分为子数组,直到每个子数组只包含一个元素。然后,该算法将这些小的子数组归并为稍大的有序子数组,直到最后形成一个有序的数组。 

     1 /**
     2  * @author zhengbinMac
     3  */
     4 public class mergeSort {
     5     
     6     public static void main(String[] args) {
     7         int[] list = {2, 3, 2, 5, 6, 1, -2, 3, 14, 12};
     8         mergeSort(list);
     9         for (int i = 0; i < list.length; i++) {
    10             System.out.print(list[i]+" ");
    11         }
    12     }
    13     
    14     public static void mergeSort(int[] list) {
    15         if(list.length > 1) {
    16             // 拆分过程
    17             // 第一半儿
    18             int[] firstHalf = new int[list.length / 2];
    19             System.arraycopy(list, 0, firstHalf, 0, list.length / 2);
    20             // 将这一半儿再拆成两半儿
    21             mergeSort(firstHalf);
    22             
    23             // 第二半儿
    24             int secondHalfLength = list.length - list.length / 2;
    25             int[] secondHalf = new int[secondHalfLength];
    26             System.arraycopy(list, list.length / 2, secondHalf, 0, secondHalfLength);
    27             // 将这一半儿再拆成两半儿
    28             mergeSort(secondHalf);
    29             
    30             // 将两半儿数组归并成一个新的有序数组temp
    31             int[] temp = merge(firstHalf, secondHalf);
    32             // 将temp赋给原始数组list
    33             System.arraycopy(temp, 0, list, 0, temp.length);
    34         }
    35     }
    36     
    37     private static int[] merge(int[] list1, int[] list2) {
    38         // 将拆分出来的两个数组归并为排好序的一个数组
    39         int[] temp = new int[list1.length + list2.length];
    40         int current1 = 0; // 指向list1当前考虑的元素
    41         int current2 = 0; // 指向list2当前考虑的元素
    42         int current3 = 0; // 指向temp当前考虑的元素
    43         
    44         while(current1 < list1.length && current2 < list2.length) {
    45             if(list1[current1] < list2[current2]) {
    46                 // 如果较小的元素在list1中,current1增加1
    47                 temp[current3++] = list1[current1++];
    48             }else {
    49                 // 如果较小的元素在list2中,current2增加1
    50                 temp[current3++] = list2[current2++];
    51             }
    52         }
    53         // 如果list1和list2中仍有未移动的元素,就将它们复制到temp中
    54         while(current1 < list1.length) {
    55             temp[current3++] = list1[current1++];
    56         }
    57         while(current2 < list2.length) {
    58             temp[current3++] = list2[current2++];
    59         }
    60         // 将temp作为一个新的有序数组返回
    61         return temp;
    62     }
    63 }
     1 package One;
     2 
     3 public class Test_sort {
     4 
     5     public static void main(String[] args) {
     6         int[] a = { 2, 9, 5, 4, 8, 1 };
     7         // sort(bubble_sort);
     8         quick_sort(a, 0, a.length - 1);
     9         for (int i = 0; i < a.length; i++) {
    10             System.out.print(a[i] + " ");
    11         }
    12     }
    13 
    14     // 冒泡排序
    15     public static int[] bubble_sort(int[] a) {
    16         // 设置判断,进行优化
    17         // 如果某次遍历中没有发生交换,那么就不用再进行下去,因为排序已完成
    18         boolean ac = true;
    19         for (int k = 1; k < a.length & ac; k++) {
    20             ac = false;
    21             for (int i = 0; i < a.length - 1; i++) {
    22                 if (a[i] > a[i + 1]) {
    23                     int temp = a[i];
    24                     a[i] = a[i + 1];
    25                     a[i + 1] = temp;
    26                     ac = true;
    27                 }
    28             }
    29         }
    30         return a;
    31     }
    32 
    33     // 快速排序
    34     public static int[] quick_sort(int s[], int l, int r) {
    35         if (l < r) {
    36             // Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
    37             int i = l, j = r, x = s[l];
    38             while (i < j) {
    39                 // 从右向左找第一个小于x的数
    40                 while (i < j && s[j] >= x)
    41                     j--;
    42                 if (i < j)
    43                     s[i++] = s[j];
    44 
    45                 // 从左向右找第一个大于等于x的数
    46                 while (i < j && s[i] < x)
    47                     i++;
    48                 if (i < j)
    49                     s[j--] = s[i];
    50             }
    51             s[i] = x;
    52             quick_sort(s, l, i - 1); // 递归调用 从右至左
    53             quick_sort(s, i + 1, r); // 从左至右
    54         }
    55         return s;
    56     }
    57 }
  • 相关阅读:
    JavaScript 基础第七天(DOM的开始)
    JavaScript 基础第六天
    JavaScript 基础第五天
    JavaScript 基础第四天
    JavaScript 基础第三天
    JavaScript 基础第二天
    观《幸福终点站》有感
    山东移动2014校园招聘笔试
    Genymotion虚拟Android不能联网的一种解决方法
    关于Thinkpad E420双显卡驱动安装和切换的问题
  • 原文地址:https://www.cnblogs.com/zhengbin/p/5335095.html
Copyright © 2011-2022 走看看