• 2016/1/10 三种排序方法 二分法排序 快速排序 冒泡排序


    //排序和查找是数据结构与算法设计的重要内容
    /*
    排序主要包括
    1.插入排序:又包括直接插入排序、二分法插入排序、表插入排序、Shell排序
    2.选择排序:包括直接选择排序、堆排序
    3.交换排序:冒泡排序、快速排序
    4.分配排序:主要有基数排序
    5.归并排序:主要有内排序、外排序
    注:以下程序均在本人电脑上通过完整的数据测试
    */
    /////////////////////////////////////////////////////////
    /////////////1.冒泡排序//////////////////////////////////
    /////////////////////////////////////////////////////////
    /*算法分析:

    依次比较相邻的两个数,将大数放在前面,小数放在后面。
    即首先比较第1个和第2个数,将大数放前,小数放后。然
    后比较第2个数和第3个数,将大数放前,小数放后,如此
    继续,直至比较最后两个数,将大数放前,小数放后,此
    时第一趟结束,在最后的数必是所有数中的最小数。重复
    以上过程,仍从第一对数开始比较(因为可能由于第2个数
    和第3个数的交换,使得第1个数不再大于第2个数),将大
    数放前,小数放后,一直比较到最小数前的一对相邻数,
    将大数放前,小数放后,第二趟结束,在倒数第二个数中得
    到一个新的最小数。如此下去,直至最终完成排序。
    */
    public class MaoPao {
    public void BubbleSort(int a[]) {
      int temp = 0;
      for (int i = 0; i < a.length; i++) {
        for (int j = 0; j < a.length - i - 1; j++) {
        if (a[j] > a[j + 1]) {
          temp = a[j];
          a[j] = a[j + 1];
          a[j + 1] = temp;
    }
    }
    }
      for (int item : a) {
        System.out.println(item);
    }
    }
    public static void main(String[] args) {
    MaoPao mp = new MaoPao();
    int[] a = { 49, 38, 65, 97, 76, 13, 27 };
    mp.BubbleSort(a);
    }
    }

    /////////////////////////////////////////////////////////
    /////////////2.快速排序//////////////////////////////////
    /////////////////////////////////////////////////////////
    /**算法分析:
    *
    * 快速排序对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的
    * 两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分
    * 数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
    *
    * 设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键
    * 数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一
    * 躺快速排序。一躺快速排序的算法是:
      1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;
      2)以第一个数组元素作为关键数据,赋值给X,即 X=A[0];
      3)从J开始向前搜索,即由后开始向前搜索(J=J-1),找到第一个小于X的值,让该值与X交换;
      4)从I开始向后搜索,即由前开始向后搜索(I=I+1),找到第一个大于X的值,让该值与X交换;
      5)重复第3、4步,直到 I=J;
      例如:待排序的数组A的值分别是:(初始关键数据:X=49)
      A[0] 、 A[1]、 A[2]、 A[3]、 A[4]、 A[5]、 A[6]:
       49 38 65 97 76 13 27
      进行第一次交换后: 27 38 65 97 76 13 49
      ( 按照算法的第三步从后面开始找)
      进行第二次交换后: 27 38 49 97 76 13 65
      ( 按照算法的第四步从前面开始找>X的值,65>49,两者交换,此时:I=3 )
      进行第三次交换后: 27 38 13 97 76 49 65
      ( 按照算法的第五步将又一次执行算法的第三步从后开始找
      进行第四次交换后: 27 38 13 49 76 97 65
      ( 按照算法的第四步从前面开始找大于X的值,97>49,两者交换,此时:J=4 )
      此时再执行第三步的时候就发现I=J,从而结束一躺快速排序,那么经过一趟快速排序之后的结果是:
    27 38 13 49 76 97 65,即所以大于49的数全部在49的后面,所以小于49的数全部在49的前面。
      快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分
    进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列变成一个有序的序列,
    根据这种思想对于上述数组A的快速排序的全过程如图6所示:
      初始状态 {49,38,65,97,76,13,27}
      进行一次快速排序之后划分为 {27 38 13} 49 {76 97 65}
      分别对前后两部分进行快速排序 {27 38 13} 经第三步和第四步交换后变成 {13 27 38} 完成排序。
      {76 97 65} 经第三步和第四步交换后变成 {65 76 97} 完成排序。
    *
    */

    public class QuickSort {
    public int partition(int[] a, int i, int j) {//分割排序
      int key = a[i];
        while(i < j) {
          while(i < j && a[j] >= key) //找出第一个比key小,并记下j值
          j--;
          a[i] = a[j];//将a[j]移至a[i]处
        while(i < j && a[i] <= key)//找出第一个比key大,并记下i值
          i++;
          a[j] = a[i];//将a[i]移至a[j]处
    }
      a[i] = key;//此时完成一趟排序
      return i;//此时i=j,记下i的值
    }

      public void sort(int[] a, int i, int j) {//递归调用分割
        if(i < j) {
          int n = partition(a,i,j);//排一次序列,并获取关键值的位置
          sort(a,i,n-1);//左递归
          sort(a,n+1,j);//右递归
    }
    }
    public static void main(String[] args) {
      int[] a = {49,38,65,97,76,13,27};
        new QuickSort().sort(a, 0, 6);
        for(int item : a) {
        System.out.println(item);
    }
    }

    }


    /////////////////////////////////////////////////////////
    /////////////3.折半(二分)法查找////////////////////////
    /////////////////////////////////////////////////////////
    /**算法分析
    *
    * 将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,
    * 即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中
    * 点元素,则将待查序列缩小为左半部分,否则为右半部分。通过一次
    * 比较,将查找区间缩小一半。
      折半查找是一种高效的查找方法。它可以明显减少比较次数,提高查
    找效率。但是,折半查找的先决条件是查找表中的数据元素必须有序。

    * 虽然二分(折半)查找的效率高,但是要将表按关键字排序。而排序本身是一
    * 种很费时的运算。即使采用高效率的排序方法也要花费 O(n lg n)
    * 的时间。
      二分查找只适用顺序存储结构。为保持表的有序性,在顺序结构里插
    入和删除都必须移动大量的结点。因此,二分查找特别适用于那种一经建
    立就很少改动、而又经常需要查找的线性表。
      对那些查找少而又经常需要改动的线性表,可采用链表作存储结构,
    进行顺序查找。链表上无法实现二分查找

    */
    import java.util.Arrays;

    public class Search{
    public void HalfSearch(int[] a, int b) {
      Arrays.sort(a);//系统排序
      int low = 0;
      int high = a.length - 1;
      int mid = (low + high) / 2;
      while ((mid != low) && (mid != high)) {
        if (b <= a[mid]) {
          high = mid;
        mid = (low + high) / 2;
      }

        else {
          low = mid;
          mid = (low + high) / 2;
    }
    }
        if ((b == a[low]) || (b == a[high])) {
          System.out.println(b + "在数组a中");
        }

         else {
          System.out.println(b + "不在数组a中");
    }
    }
    public static void main(String[] args){
          Search s=new Search();
          int[] a={11,41,17,18,14,16,20,45};
          s.HalfSearch(a,20);
    }
    }

  • 相关阅读:
    列表元素的删,添,复制
    序列的通用操作
    列排(list)排序
    列表(list)
    str的常用操作
    复制/etc/profile至/tmp/目录,用查找替换命令删除/tmp/profile文件中的行首的空白字符;在vim中设置tab缩进为4个字符
    Linux上的文件管理类命令都有那些,其中常用的使用方法及相关示例演示
    总结软连接和硬连接区别,并用实例操作
    文件的元信息有那些,分别表示什么含义,如何查看?如何修改文件的时间戳信息?
    Linux发行版的系统目录名称命名规则以及用途
  • 原文地址:https://www.cnblogs.com/haodayikeshu/p/5119156.html
Copyright © 2020-2023  润新知