快速排序和分治排序介绍

快速排序让我看了很久,也折磨了我很长时间,因为大体上的思路我是有了,但是写代码时总是出现各种问题,要想把它调试出来对我个人来说还是有一定难度的,而且因为工作和偷懒的原因,导致之前调试不出来的错误放了很久,今天终于出来啦,还是有些小激动的哦,下面来分享一下我的代码并做一点点说明。

  要学会快速排序,就必须先要学会分治法,分治的思想是给一串乱序的数字(数字是假设,也可以是其他的对象,当然方法的参数可以自己定义哦,我在这里假设有一个整型的数组吧)然后给他一个中间数,分治法会把这些数字以给他的那个是中间数为分界分为两部分,一部分在中间数的左边,另一部分在右边,以这个数为分界点,两边的数现在还是乱序的,我给他定义的方法如下:

//left是数组的想分治部分的左端点,right是数组分治部分的总端点,如长度为10的数组,我想对前5个整数进行分治,则传0,4即可
  public int signalFenZhi(int left,int right){
    if(left<0||left>n-1||right<0||right>n-1){
      return -1;
    }
    int temp = test[left];
    int j=right;
    int i=left;

    while(i<j){
      while(test[j]>=test[left]&&i<j){
        j--;
      }
      while(test[i]<=test[left]&&i<j){
        i++;
      }

      if(i<j){
        temp = test[i];
        test[i]=test[j];
        test[j]=temp;
      }
    }

    if(i==j){
      temp = test[i];
      test[i]=test[left];
      test[left]=temp;
    }

    for(int m=0;m<n;m++){
      System.out.print(test[m]+"   ");
    }

    return i;

  }

当然,也可以把那个中间数当参数传进来,现在我只是单纯的以数组的传进来的第left数做为分界数,这只是为了说明。

  明白了分治,那么快速排序也就简单了,那就是对已经分为两部分的数再进行分治,依次类推,直到全部的数字都有序为止,代码如下:

public void quickSort(int left,int right){
    if(right-left<1){
      return ;
    }else{
      int point = this.signalFenZhi(left, right);
      System.out.println(point);
      //if(point!=left&&point!=right){
        quickSort(left,point-1);
        quickSort(point+1,right);
      //}
    }
  }

快速排序的效率在众多的排序算法中是很优秀的,时间复杂度为O(N*log2n),但是如果分治的分界点选的不好的话,时间复杂度将会降到(n的平方),因为如果正好这个数组是有序的,然后我们每次都取传过来的最左端的数,那么效率就会很低,所以要避免发生这种情况,如果检测所有的选项,那么将会很花时间,所以一个折中的办法 ,就是把最左端的数和最右端的数加上一个中间的数,找到他们三个中间的数,以这个为分界值就会变的好一点,在上面方法的基础上,修改以后的代码如下,但是我做完了以后这样的做法不是很好,应该把分界值也当做传给分治的方法会好些,细心的朋友可以自己试一下,我在这里就不试了哈,大体上是一样的哦!

package com.jll;

public class FenZhi {

  int[] test;

  int n=10;

  public FenZhi(){
    test = new int[10];

    for(int i=0;i<n;i++){
      test[i]=(int)(Math.random()*100)+1;
      System.out.print(test[i]+"   ");
    }
    System.out.println();
  }

  public FenZhi(int n){
    if(n>0){
      this.n=n;
      test = new int[n];

      for(int i=0;i<n;i++){
        test[i]=(int)(Math.random()*100)+1;
      }
    }
  }

  public int signalFenZhiMajorizationFirst(int left,int right){
    if(left<0||left>n-1||right<0||right>n-1||left>=right){
      return -1;
    }

    if(right-left>=2){
      int middle = (right+left)/2;
      if(test[left]>test[middle]){
        int temp = test[middle];
        test[middle] = test[left];
        test[left] = temp;
      }
      if(test[left]>test[right]){
        int temp = test[left];
        test[left] = test[right];
        test[right] = temp;
      }
      if(test[middle]>test[right]){
        int temp = test[middle];
        test[middle] = test[right];
        test[right] = temp;
      }
      int temp = test[middle];
      test[middle] = test[left];
      test[left] = temp;
      int j=right-1;
      int i=left+1;

      while(i<j){
        while(test[j]>=test[left]&&i<j){
          j--;
        }
        while(test[i]<=test[left]&&i<j){
          i++;
        }

        if(i<j){
          temp = test[i];
          test[i]=test[j];
          test[j]=temp;
        }
      }
      if(i==j){
        temp = test[i];
        test[i]=test[left];
        test[left]=temp;
      }

      /*if(i==j){
        temp = test[middle];
        test[middle]=test[i];
        test[i]=temp;
      }*/

      /*for(int m=0;m<n;m++){
        System.out.print(test[m]+"   ");
      }*/

      return i;
    }else {
      if(test[right]<test[left]){
        int temp = test[right];
        test[right] = test[left];
        test[left] = temp;
      }
      return right;
    }
  }

  public void quickSortMajorizationFirst(int left,int right){
    if(right-left<1){
      return ;
    }else{
      int point = this.signalFenZhiMajorizationFirst(left, right);
      System.out.println("the point is:"+point);
      quickSortMajorizationFirst(left,point-1);
      quickSortMajorizationFirst(point+1,right);
    }
  }

  public static void main(String[] args) {
    FenZhi f = new FenZhi();
    System.out.println(f.signalFenZhiMajorizationFirst(0, 9));
    System.out.println();
    f.quickSortMajorizationFirst(0,f.n-1);

    //f.quickSort(0,f.test.length-1);
    for(int i:f.test){
      System.out.print(i+" ");
    }
  }
}

代码运行如下:

95   40   64   18   78   23   73   84   40   

the point is:4
the point is:1
the point is:3
the point is:7
the point is:6
the point is:9
18 23 40 40 64 73 78 84 95

以上就是我学习到的东西,记录一下,以备后面查阅。

(0)

相关推荐

  • 快速排序和分治排序介绍

    快速排序让我看了很久,也折磨了我很长时间,因为大体上的思路我是有了,但是写代码时总是出现各种问题,要想把它调试出来对我个人来说还是有一定难度的,而且因为工作和偷懒的原因,导致之前调试不出来的错误放了很久,今天终于出来啦,还是有些小激动的哦,下面来分享一下我的代码并做一点点说明. 要学会快速排序,就必须先要学会分治法,分治的思想是给一串乱序的数字(数字是假设,也可以是其他的对象,当然方法的参数可以自己定义哦,我在这里假设有一个整型的数组吧)然后给他一个中间数,分治法会把这些数字以给他的那个是中间数

  • C++归并法+快速排序实现链表排序的方法

    本文主要介绍了C++归并法+快速排序实现链表排序的方法,分享给大家,具体如下: 我们可以试用归并排序解决: 对链表归并排序的过程如下. 找到链表的中点,以中点为分界,将链表拆分成两个子链表.寻找链表的中点可以使用快慢指针的做法,快指针每次移动 2 步,慢指针每次移动 1步,当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点. 对两个子链表分别排序. 将两个排序后的子链表合并,得到完整的排序后的链表 上述过程可以通过递归实现.递归的终止条件是链表的节点个数小于或等于 1,即当链表为空或者链

  • Python实现的插入排序,冒泡排序,快速排序,选择排序算法示例

    本文实例讲述了Python实现的插入排序,冒泡排序,快速排序,选择排序算法.分享给大家供大家参考,具体如下: #!/usr/bin/python # coding:utf-8 #直接插入排序 def insert_sort(list): for i in range(len(list)): Key = list [i] #待插入元素 j = i - 1 while(Key < list[j] and j >= 0): list[j+1] = list[j] #后移元素 list[j] = Ke

  • MySQL限制查询和数据排序介绍

    目录 一.限制查询 1.指定从第几行起,返回多少行 2.取最大值 3.取最小值 4.分页 二.数据排序 1.年龄大于10的根据id进行降序排序 2.年龄大于10的按照id进行升序排序 一.限制查询 我们通过limit可以限制返回结果的行数 select * from 表名 limit count; select * from users limit 3; 1.指定从第几行起,返回多少行 select * from 表名 limit start,count; select * from users

  • java数组排序示例(冒泡排序、快速排序、希尔排序、选择排序)

    快速排序法主要是运用了Arrays中的一个方法Arrays.sort()实现. 冒泡法是运用遍历数组进行比较,通过不断的比较将最小值或者最大值一个一个的遍历出来. 选择排序法是将数组的第一个数据作为最大或者最小的值,然后通过比较循环,输出有序的数组. 插入排序是选择一个数组中的数据,通过不断的插入比较最后进行排序. 复制代码 代码如下: package com.firewolf.sort; public class MySort { /**  * @param args  */ public s

  • JSON 数字排序多字段排序介绍

    复制代码 代码如下: //排序数组 function SortBy(field, reverse, primer) { reverse = (reverse) ? -1 : 1; return function (a, b) { a = a[field]; b = b[field]; if (typeof (primer) != 'undefined') { a = primer(a); b = primer(b); } if (a < b) return reverse * -1; if (a

  • java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述

    算法是在有限步骤内求解某一问题所使用的一组定义明确的规则.通俗点说,就是计算机解题的过程.在这个过程中,无论是形成解题思路还是编写程序,都是在实施某种算法.前者是推理实现的算法,后者是操作实现的算法. 一个算法应该具有以下五个重要的特征: 1.有穷性: 一个算法必须保证执行有限步之后结束: 2.确切性: 算法的每一步骤必须有确切的定义: 3.输入:一个算法有0个或多个输入,以刻画运算对象的初始情况: 4.输出:一个算法有一个或多个输出,以反映对输入数据加工后的结果.没有输出的算法是毫无意义的:

  • C语言常见排序算法之交换排序(冒泡排序,快速排序)

    目录 前言 1.交换排序——冒泡排序 1.1 算法思想 1.2 动图演示 1.3 冒泡最好的情况 2. 交换排序——快速排序 2.1 快速排序——挖坑法 快排的缺点 三数取中法 2.3 快速排序——左右指针法 2.4 前后指针法 前言 本期为大家带来的是常见排序算法中的交换排序,主要有冒泡排序,快速排序,快排分享了三种算法:挖坑法,左右指针法,前后指针法,以及两种优化方式:解决快排最坏情况的“三数取中”,避免递归次数过多的"小区间优化", 基本思想:所谓交换,就是根据序列中两个记录键值

  • 10个python3常用排序算法详细说明与实例(快速排序,冒泡排序,桶排序,基数排序,堆排序,希尔排序,归并排序,计数排序)

    我简单的绘制了一下排序算法的分类,蓝色字体的排序算法是我们用python3实现的,也是比较常用的排序算法. Python3常用排序算法 1.Python3冒泡排序--交换类排序 冒泡排序(Bubble Sort)也是一种简单直观的排序算法. 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来. 走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端. 作为最简单的排序算法

  • Python实现快速排序和插入排序算法及自定义排序的示例

    一.快速排序 快速排序(Quicksort)是对冒泡排序的一种改进.由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 快速排序,递归实现 def quick_sort(num_list): """ 快速排序 """ if num_li

随机推荐