A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 柳雷 中级黑马   /  2012-7-25 13:21  /  1565 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 柳雷 于 2012-7-26 16:21 编辑

快速排序
算法思想:
每趟取一个参照记录,称为枢轴(或支点),先从右向左,逐个记录与枢轴比较,如果逆序则交换,再从左向右,逐个记录与枢轴比较,如果逆序则交换,反复进行,直到左右相遇,结束一趟排序,并将枢轴记录交换到最终所在的位置上。所有大于枢轴的记录记录在右边,小于的在左边,一趟快速排序过程称为一个划分。然后分别对左右两部分进行相同的划分(或分割),得到4部分,再对每部分做相同划分,依次继续下去,直到每个小部分只有一个记录,排序结束。显然,对部分的划分操作完全相同,只是范围需修改,因此可以用递归实现,且最多经过[log 2 n +1)趟划分,排序结束。
算法实现:分解为两个函数,一趟划分函数,递归调用函数。
以下是快速排序的非递归算法实现
  int  partition ( RecTypr  R[ ] ,  int  low , int  high  )
         {  i= low ; j = high ; R[0] = R ; x = R.key ;
            while ( i < j )
               {  while ( i < j && R[j].key >= x ) j - - ;
                  if ( i < j ) R = R[j] ;  //
                  while ( i < j && R[j].key <= x )  i ++ ;
                  if ( i < j ) R[j] = R ;
                }
            R = R[0] ;
            return  i ;
         }
   Void  quicksort (RecTypr  R[ ] ,  int  n )
           {  typedef  struct
                 {  int  low , high  
} Node ;
             Node s[n+1] ;
             int  top = 1 ;
s[top].low = 1 ;  s[top].high = n ;
             while ( top > 0 )
                 {  ss = s[top].low ;  tt = s[top].high ;  top - - ;
                    if ( ss < tt )
                       {  k = partition ( R ,  ss ,  tt ) ;
                          if ( k – ss > 1 )
                            {  s[++top].low = ss ;
                              s[top].high = k – 1 ;
                            }
                          if ( k – tt > 1 )
                            { s[++top].low = k+1 ;
                              S[top].high = tt ;
                            }
                        }
                  }
            }

2 个回复

倒序浏览
  1. package com.itheima.util;

  2. /**
  3. * 排序工具类
  4. *
  5. * @author mrng
  6. *
  7. */
  8. public class SortUtils {
  9.         /**
  10.          * 快速排序 如果调用此方法,次方法会再掉用quickSort(String[] strArr, int left, int rigth)方法
  11.          * left默认为0, right默认为strArr.length-1
  12.          *
  13.          * @param strArr
  14.          */
  15.         public static void quickSort(int[] arr) {
  16.                 quickSort(arr, 0, arr.length - 1);
  17.         }

  18.         /**
  19.          * 快速排序 此方法可以对数组需要排序的区间进行定制
  20.          *
  21.          * @param strArr
  22.          * @param left
  23.          * @param right
  24.          */
  25.         public static void quickSort(int[] arr, int left, int right) {
  26.                 // 数组中间的元素
  27.                 int middle = arr[(left + right) / 2];
  28.                 // 临时变量,用于交换数组元素使用
  29.                 int temp;
  30.                 // 向后搜索的指针
  31.                 int i = left;
  32.                 // 向前搜索的指针
  33.                 int j = right;

  34.                 do {
  35.                         while (arr[i] < middle && i < right)
  36.                                 i++; // 找出左边比中间值大的数
  37.                         while (arr[j] > middle && j > left)
  38.                                 j--; // 找出右边比中间值小的数
  39.                         if (i <= j) { // 将左边大的数和右边小的数进行交换
  40.                                 temp = arr[i];
  41.                                 arr[i] = arr[j];
  42.                                 arr[j] = temp;

  43.                                 i++;
  44.                                 j--;
  45.                         }
  46.                 } while (i <= j); // 当两个指针交错时停止

  47.                 // 将数组分开两半,确定每个数字的正确位置
  48.                 if (i < right) {
  49.                         quickSort(arr, i, right);
  50.                 }
  51.                 if (j > left) {
  52.                         quickSort(arr, left, j);
  53.                 }
  54.         }

  55.         /**
  56.          * 冒泡排序法
  57.          *
  58.          * @param arr
  59.          */
  60.         public static void BubbleSort(int[] arr) {
  61.                 for (int i = 0; i < arr.length - 1; i++) {
  62.                         for (int j = 0; j < arr.length - i - 1; j++) {
  63.                                 if (arr[j] > arr[j + 1]) {
  64.                                         arr[j] = arr[j] ^ arr[j + 1];
  65.                                         arr[j + 1] = arr[j] ^ arr[j + 1];
  66.                                         arr[j] = arr[j] ^ arr[j + 1];
  67.                                 }
  68.                         }
  69.                 }
  70.         }

  71.         /**
  72.          * 选择排序法
  73.          */
  74.         public void SelectSort(int[] arr) {
  75.                 for (int i = 0; i < arr.length - 1; i++) {
  76.                         for (int j = i + 1; j < arr.length; j++) {
  77.                                 if (arr[i] > arr[j]) {
  78.                                         arr[i] = arr[i] ^ arr[j];
  79.                                         arr[j] = arr[i] ^ arr[j];
  80.                                         arr[i] = arr[i] ^ arr[j];
  81.                                 }
  82.                         }
  83.                 }
  84.         }
  85. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 侯宪博 于 2012-7-25 13:42 编辑

快速排序是对冒泡排序的一个升级
一趟快速排序的规则
就是设定一个枢轴,把段表分割成两段
一段中的数据都比枢轴小,另一边都比枢轴的数据大
这就是快速排序的一趟排序
然后分别对这分割完的数据段再进行快速排序
如此下去就会排出有序序列
可以利用递归的思想



首先要先定义一个方法实现一趟快速排序,并且该方法返回枢轴位置
例如:
//定义一个一趟快速排序的私有方法供内部使用
        private int yiTangSort(int[] s,int low,int high)
        {
                //定义一个变量作为枢轴的临时容器
                int pivotkey=0;
               
                pivotkey=s[low];//枢轴记录关键字
               
                //如果数据长度不小于1,就开始从数据的两端交替的向中间扫描
                while(low<high)
                {
                        while(low<high&&s[high]>=pivotkey)//将比枢轴小的数据移到低端
                                high--;
                        s[low]=s[high];
                        while(low<high&&s[low]<=pivotkey)//将比枢轴大的数据移到高端
                                low++;
                        s[high]=s[low];
                }
                s[low]=pivotkey;//将枢轴添加到指定位置
                return low;//返回枢轴位置
        }



然后再定义一个方法判断枢轴并递归调用一趟排序的方法
例如
//定义一个私有快速排序的方法供内部使用
        private void quickSort(int[] s,int low,int high)
        {
                int pivot=0;//定义一个变量用来接受枢轴的位置
               
                if(low<high)//如果该数据段长度大于1开始排序和递归
                {
                        pivot=yiTangSort(s,low,high);
                        quickSort(s,low,pivot-1);
                        quickSort(s,pivot+1,high);
                }
                        
        }


然后对外部暴露出去一个快速排序的方法
例如:
//定义一个快速排序的方法供外部使用
        public void kuaiSuPaiXu(int[] s)
        {
                int low=0;
                int high=s.length-1;
                quickSort(s,low,high);
        }
以上只是三个方法
楼主可以试着把他们封装在一个类中,以实现完整的快速排序

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马