`
lvwenwen
  • 浏览: 953770 次
  • 性别: Icon_minigender_1
  • 来自: 魔都
社区版块
存档分类
最新评论

快速排序算法原理与实现/交换排序

阅读更多
快速排序的大致思想为取到中间位置的元素,其他元素和其一一比较,分列左右,然后左右再迭代使用以上步骤

Java代码 
quickSort:function(arr) { 
    if (arr.length <= 1) {return arr;} 
    var pivotIndex = Math.floor(arr.length / 2); 
    var pivot = arr.splice(pivotIndex, 1); 
    var left = []; 
    var right = []; 
    for (var i = 0; i < arr.length; i++){ 
        if (arr[i] < pivot){ 
            left.push(arr[i]); 
            }else{ 
            right.push(arr[i]); 
            } 
        } 
    return quickSort(left).concat(pivot, quickSort(right)); 
}, 
quickSortObjArr:function(objArr,key) { 
    if (objArr.length <= 1) {return objArr;} 
    var pivotIndex = Math.floor(objArr.length / 2); 
    //var pivot = objArr.splice(pivotIndex, 1); 
    var pivot = objArr[pivotIndex]; 
    objArr.splice(pivotIndex, 1);    
    var left = []; 
    var right = []; 
    for (var i = 0; i < objArr.length; i++){      
        if (objArr[i][key] < pivot[key]){             
            left.push(objArr[i]); 
            }else{ 
            right.push(objArr[i]); 
            } 
        } 
    return quickSortObjArr(left,key).concat(pivot, quickSortObjArr(right,key)); 


快速排序的基本思想是
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序的一般性策略
设要排序的数组是A[0]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟排序。
具体步骤
以第一个数据作为基准数据,并赋值给temp变量。
定义两个变量i,j使其初始值i=1,j=N。
无限遍历直到找到基准数的位置为止,寻找基准数位置方法如下,
由j开始向前搜索即(j = j-1),直到找到第一个A[j] < temp时停止向前搜索。
由i开始向后搜索即(i = i+1),直到找到第一个A[i] > temp时停止向后搜索。
当 i < j 时 交换A[i] 和 A[j] 的位置,否则退出遍历。即j就是基准数的最终位置。
将基准数与A[j]的位置互换,第一趟排序完成。
将比基准数小的值列与比基准数大的值列继续递归排序从而最终排序。
Java代码 
/**
* 快速排序
* @param arr 待排数组
* @param low 待排数组低位下标
* @param higth 待排数组高位下标
*/ 
public void quickSort(int[] arr,int low,int higth){ 
    //{3,2,1,20,6,5,16,8}  
    if(low < higth){ 
        int temp = arr[low]; 
        int i = low + 1; 
        int j = higth; 
        for(;;){ 
            while((i <=higth)&&arr[i] < temp){ 
                i++; 
            }  
            while((j >=low)&&arr[j] > temp){ 
                j--; 
            } 
            if(i < j){ 
                swap(arr, i, j); 
            }else{ 
                break; 
            } 
             
        } 
        swap(arr, low, j); 
        quickSort(arr, low, j-1); 
        quickSort(arr, j+1, higth); 
    } 
 
    // 

 
public void swap(int[] arr, int i,int j){ 
    int temp = arr[j]; 
    arr[j] = arr[i]; 
    arr[i] = temp; 


思想

快速排序算法  例 确定1个数值 大的在后面 小的那前面 在以数值为中心分割 前后2个数组分别做快速排序~如此递归!

下面是1个demo

设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
  一趟快速排序的算法是:
  1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;
  2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];
  3)从J开始向前搜索,即由后开始向前搜索(J=J-1),找到第一个小于key的值A[J],并与key交换;
  4)从I开始向后搜索,即由前开始向后搜索(I=I+1),找到第一个大于key的A[I],与key交换;
  5)重复第3、4、5步,直到 I=J; (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i, j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束。)
  例如:待排序的数组A的值分别是:(初始关键数据:X=49) 注意关键X永远不变,永远是和X进行比较,无论在什么位子,最后的目的就是把X放在中间,小的放前面大的放后面。
  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,两者交换,此时:I=4,J=6 )
  此时再执行第三步的时候就发现I=J,从而结束一趟快速排序,那么经过一趟快速排序之后的结果是:27 38 13 49 76 97 65,即所有大于49的数全部在49的后面,所有小于49的数全部在49的前面。
java实现第一趟排序:
  public class QuickSort {
  public static void method(int[] array )
  {
  int i = 0 ;
  int j = array.length - 1;
  int k = array[0];
  while(i != j)
  {
  while(array[j] > k)
  {
  j--;
  }
  int temp = k;
  k = array[j];
  array[j] = temp;
  while (array[i] < k)
  {
  i++;
  }
  int temp1= k;
  k = array[i];
  array[i] = temp1;
  }
  if(k == array[j])
  {
  }
  }
  public static void main(String[] args)
  {
  int[] array = {49,38,65,97,76,13,27 };
  QuickSort.method(array);
  for(int i = 0; i < array.length; i++)
  {
  System.out.print(array[i] + " ");
  }
  }
  }
  运行结果:27 38 13 49 76 97 65快速排序就是递归调用此过程——在以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} 完成排序

引用:http://baike.baidu.com/view/115472.htm

快速排序是对冒泡排序的一种改进。它的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按次方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

    假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。一躺快速排序的算法是:

   1)、设置两个变量I、J,排序开始的时候I:=1,J:=N;

   2)以第一个数组元素作为关键数据,赋值给X,即X:=A[1];

   3)、从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换;

   4)、从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换;

   5)、重复第3、4步,直到I=J;

   例如:待排序的数组A的值分别是:(初始关键数据X:=49)

                   A[1]     A[2]     A[3]     A[4]     A[5]      A[6]     A[7]:

                     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}

分别对前后两部分进行快速排序    {13}    27    {38}

                                结束         结束    {49    65}    76    {97}

                                                    49   {65}         结束

                                                        结束

                          图6    快速排序全过程

1)、设有N(假设N=10)个数,存放在S数组中;

2)、在S[1。。N]中任取一个元素作为比较基准,例如取T=S[1],起目的就是在定出T应在排序结果中的位置K,这个K的位置在:S[1。。K-1]<=S[K]<=S[K+1..N],即在S[K]以前的数都小于S[K],在S[K]以后的数都大于S[K];

3)、利用分治思想(即大化小的策略)可进一步对S[1。。K-1]和S[K+1。。N]两组数据再进行快速排序直到分组对象只有一个数据为止。

如具体数据如下,那么第一躺快速排序的过程是:

数组下标: 1      2      3      4      5      6      7      8      9      10

           45     36     18     53     72     30     48     93     15      36

      I                                                                   J

(1)      36     36     18     53     72     30     48     93     15      45

      

(2)      36     36     18     45     72     30     48     93     15      53

(3)      36     36     18     15     72     30     48     93     45      53

(4)      36     36     18     15     45     30     48     93     72      53

(5)      36     36     18     15     30     45     48     93     72      53

通过一躺排序将45放到应该放的位置K,这里K=6,那么再对S[1。。5]和S[6。。10]分别进行快速排序。

一般来说,冒泡法是程序员最先接触的排序方法,它的优点是原理简单,编程实现容易,但它的缺点就是--程序的大忌--速度太慢。下面我介绍一个理解上简单但编程实现上不是太容易的排序方法,我不知道它是不是现有排序方法中最快的,但它是我见过的最快的。排序同样的数组,它所需的时间只有冒泡法的 4% 左右。我暂时称它为“快速排序法”。

     “快速排序法”使用的是递归原理,下面我结合一个例子来说明“快速排序法”的原理。首先给出一个数组{53,12,98,63,18,72,80,46, 32,21},先找到第一个数--53,把它作为中间值,也就是说,要把53放在一个位置,使得它左边的值比它小,右边的值比它大。{21,12,32, 46,18,53,80,72,63,98},这样一个数组的排序就变成了两个小数组的排序--53左边的数组和53右边的数组,而这两个数组继续用同样的方式继续下去,一直到顺序完全正确。

     我这样讲你们是不是很胡涂,不要紧,我下面给出实现的两个函数:

/*
n就是需要排序的数组,left和right是你需要排序的左界和右界,
如果要排序上面那个数组,那么left和right分别是0和9
*/

void quicksort(int n[], int left,int right)
{
int dp;
if (left<right) {

     /*
     这就是下面要讲到的函数,按照上面所说的,就是把所有小于53的数放
     到它的左边,大的放在右边,然后返回53在整理过的数组中的位置。
     */
     dp=partition(n,left,right);

     quicksort(n,left,dp-1);

     quicksort(n,dp+1,right); //这两个就是递归调用,分别整理53左边的数组和右边的数组
}
}

     我们上面提到先定位第一个数,然后整理这个数组,把比这个数小的放到它的左边,大的放右边,然后

返回这中间值的位置,下面这函数就是做这个的。
int partition(int n[],int left,int right)
{
int lo,hi,pivot,t;

pivot=n[left];
lo=left-1;
hi=right+1;

while(lo+1!=hi) {
     if(n[lo+1]<=pivot)
       lo++;
     else if(n[hi-1]>pivot)
       hi--;
     else {
       t=n[lo+1];
       n[++lo]=n[hi-1];
       n[--hi]=t;
     }
}

n[left]=n[lo];
n[lo]=pivot;
return lo;
}

     这段程序并不难,应该很好看懂,我把过程大致讲一下,首先你的脑子里先浮现一个数组和三个指针,第一个指针称为p指针,在整个过程结束之前它牢牢的指向第一个数,第二个指针和第三个指针分别为lo指针和hi指针,分别指向最左边的值和最右边的值。lo指针和hi指针从两边同时向中间逼近,在逼近的过程中不停的与p指针的值比较,如果lo指针的值比p指针的值小,lo++,还小还++,再小再++,直到碰到一个大于p指针的值,这时视线转移到hi指针,如果 hi指针的值比p指针的值大,hi--,还大还--,再大再--,直到碰到一个小于p指针的值。这时就把lo指针的值和hi指针的值做一个调换。持续这过程直到两个指针碰面,这时把p指针的值和碰面的值做一个调换,然后返回p指针新的位置。

#include<iostream>
using namespace std;
int a[200001],n;
void swap(int &a,int &b){
int tmp = a;
a = b;
b = tmp;
}
int partition(int p,int r){
int rnd = rand()%(r-p+1)+p;
swap(a[rnd],a[r]);
int pvt = r, i = p-1;
for(int j = i+1;j<r;j++)
if(a[j]<a[pvt])
swap(a[j],a[++i]);
swap(a[++i],a[pvt]);
return i;
}
void qsort(int p,int r){
if(p<r){
int q = partition(p,r);
qsort(p,q-1);
qsort(q+1,r);
}
}

交换排序:
思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。
Java代码 
public static void exchangeSort(int[] arr) { 
       for (int i = 0; i < arr.length - 1; i++) { 
           for (int j = i + 1; j < arr.length; j++) { 
              if (arr[i] > arr[j]) { 
                  int temp = arr[i]; 
                  arr[i] = arr[j]; 
                  arr[j] = temp; 
              } 
           } 
       } 
    } 
int main(){
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
qsort(0,n-1);
for(int i=0;i<n;i++)
cout<<a[i];
return 0;
}
分享到:
评论

相关推荐

    快速排序算法(c#实现)

    总的来说,快速排序是一种非常重要的排序算法,理解其工作原理并能用C#或其他编程语言实现,对于提升编程技能和解决问题的能力大有裨益。在实际项目中,根据具体场景选择合适的排序算法是优化程序性能的关键。

    数据结构 交换排序算法(c/c++)

    交换排序是一种常见的排序算法,它通过不断地交换元素来达到排序的目的。本文将深入探讨交换排序算法,特别是C/C++语言中的实现方式。 交换排序的核心思想是通过比较数组中的相邻元素,如果它们的顺序错误,就交换...

    排序算法.doc 详细讲解了插入排序、交换排序、选择排序、归并排序等排序算法的原理以及实现代码

    本文主要探讨四种基本的排序算法:插入排序、交换排序、选择排序和归并排序,这些都是内部排序的主要方法。 1. **插入排序**: - 直接插入排序是最基础的排序算法之一,它的工作原理类似于人们手动整理扑克牌。...

    算法设计与分析-1排序算法性能分析-冒泡/选择/插入/合并/快速排序-pre ppt

    本篇文章将详细讨论几种常见的排序算法:选择排序、冒泡排序、插入排序、合并排序以及快速排序,分析它们的算法原理、时间效率,并通过经验分析验证理论分析的准确性。 **1. 选择排序(Selection Sort)** 选择排序...

    排序算法(C语言实现)

    本资源提供了三种经典的排序算法的C语言实现:堆排序、直接插入排序和快速排序。 首先,让我们详细了解这些排序算法。 1. **直接插入排序**: 直接插入排序是一种简单的排序算法,它的工作原理类似于我们手动排序...

    快速排序算法以及归并算法

    在提供的代码片段中,`Project18_qSort` 类实现了快速排序算法。具体步骤如下: 1. **初始化**:定义一个数组 `a`,并调用 `qSort` 方法进行排序。 2. **递归调用**:在 `qSort` 方法中,首先检查 `from` 和 `to` ...

    C/C++实现三路快速排序算法原理

    三路快速排序是一种改进的快速排序算法,尤其适用于处理包含大量重复元素的数组。传统的快速排序在遇到重复元素时可能会导致分治过程中左右子序列的不平衡,降低排序效率。三路快速排序通过将数组分为三部分,分别...

    快速排序算法C语言实现与优化.pdf

    ### 快速排序算法C语言实现与优化 #### 一、快速排序算法的基本原理 快速排序算法是一种基于分治策略的高效排序算法。其基本思想是通过一趟排序将待排序的记录分隔成独立的两部分,其中一部分的所有记录比另一部分...

    数据结构快速排序算法实现

    #### 快速排序算法原理 快速排序的核心在于**分区操作**(partitioning)。该操作选择一个枢轴,通过一系列比较和交换操作,将数组分为两个部分,使得左侧的元素都不大于枢轴,右侧的元素都不小于枢轴。分区操作...

    快速排序算法和冒泡排序效率对比

    本篇文章将深入探讨这两种排序算法的原理、效率以及它们在C#编程语言中的实现。 首先,让我们了解冒泡排序。冒泡排序是一种简单直观的排序方法,它通过重复遍历待排序的数列,比较相邻元素并根据需要交换位置,以使...

    7种常用排序算法实现(C++)(冒泡排序、选择排序、直接插入排序、希尔排序、堆排序、归并排序以及快速排序)

    冒泡排序是最基础的排序算法之一,通过重复遍历待排序序列,比较相邻元素并交换位置来实现排序。如果前一个元素大于后一个元素,它们就会交换位置,这样最大的元素会逐渐"冒泡"到序列末尾。时间复杂度为O(n^2)。 2...

    使用python实现常用算法,包括冒泡排序/选择排序/插入排序/归并排序/快速排序/堆排序/二分查找/并查集/最小生成树/最小路

    冒泡排序是一种简单的排序算法,它通过重复遍历待排序的数列,一次比较两个元素,如果顺序错误就交换位置。这个过程会一直重复,直到没有再需要交换,也就是说该数列已经排序完成。Python实现冒泡排序的关键在于两...

    C语言快速排序算法实现

    1. **快速排序算法原理**: 快速排序是一种分治策略的典型应用。其核心在于选择一个基准元素,然后将数组分为两部分,所有小于基准的元素放到基准前面,所有大于基准的元素放到基准后面,这个过程称为分区操作。...

    一种快速排序算法的C语言实现.pdf

    综上所述,快速排序算法的C语言实现对于理解排序算法的原理和提高程序设计水平具有重要意义。通过对快速排序算法的学习和实践,不仅可以加深对算法性能的理解,而且能够提高解决实际问题的能力。

    数据结构--快速排序算法的实现

    快速排序是一种高效的排序算法,由英国计算机科学家C.A.R. Hoare在1960年提出。它的基本思想是分治法(Divide and Conquer),将一个大问题分解为小问题来解决,最终合并小问题的结果得到原问题的解。在数据结构中,...

    分治算法实验(用分治法实现快速排序算法).pdf

    本实验让我更深入地理解了快速排序算法的原理和实现,也让我明白了随机化的重要性在排序算法中的应用。通过实验,我学习到了如何使用分治法来实现快速排序算法,并对其性能进行分析和优化。 七、结论 本实验总结了...

    常用排序算法分析与实现(Java版)

    ### 常用排序算法分析与实现(Java版) #### 插入排序 **1. 直接插入排序** 直接插入排序是一种简单的排序方法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并...

    7大排序算法实现程序(快速排序,冒泡排序,选择排序,归并排序,插入排序,希尔排序,堆排序)

    本资源提供了七大经典排序算法的实现程序,包括快速排序、冒泡排序、选择排序、归并排序、插入排序、希尔排序和堆排序。下面将逐一详细介绍这些排序算法及其原理。 1. 快速排序:由C.A.R. Hoare提出,是一种采用...

    演示快速排序算法(12KB)

    通过分析这些文件,我们可以深入学习快速排序算法的实现细节,理解其工作原理,并且通过可视化界面更好地理解排序过程。对于编程初学者来说,这是一份很好的学习资源,能够帮助他们掌握快速排序这一重要的排序算法。...

    C++语言快速排序算法的实现

    在这个C++实现的快速排序算法中,我们通常会使用递归来处理数组或向量的元素。以下是关于快速排序算法的详细解释: 1. **基本原理**: - 快速排序的流程分为三个步骤:选择一个基准元素(pivot)、分区操作和递归...

Global site tag (gtag.js) - Google Analytics