zoukankan      html  css  js  c++  java
  • 快速排序算法

    最开始学习编程,遇到排序问题,一般都是用冒泡法,因为冒泡法好理解,代码量少。但是这种算法时间复杂度高,当需要排序的元素较多时,程序运行时间很长,因此产生了快速排序算法。该算法的实现可分为以下几步:

    1. 在数组中选一个基准数(通常为数组第一个);

    2. 将数组中小于基准数的数据移到基准数左边,大于基准数的移到右边;

    3. 对于基准数左、右两边的数组,不断重复以上两个过程,直到每个子集只有一个元素,即为全部有序。

    例如有一需要排序的数组为:23,45,17,11,13,89,72,26,3,17,11,13(从小到大排序):

    选取数组第一个数23为基准数,存入temp变量中,从数组的左右两边界向中间进行遍历,定义两个指针 i 和 j,i 最开始指向数组的第一个元素,j 最开始指向数组的最后一个元素。指针 i 从左向右移动,指针 j 从右向左移动。先移动 j 指针(从右忘左移),当 j 指向的数大于基准数时,略过,j 继续往左移动,直到遇到小于等于基准数的数arr[j],将arr[j]填入arr[i]中;再移动 i 指针,当 i 指向的数小于等于基准数时,略过,i 继续往右移动,直到遇到不比基准数小的数arr[i],将arr[i]填入arr[j]中;再移动 i 指针,再移动 j 指针...(轮换移动),直到 i 和 j 指针相遇,此时将temp(基准数)填入arr[i]中即完成算法的第2个步骤。接下来分别将基准数左边和右边的数组按照以上方法进行聚合,直到每个子集只有一个元素,即排序完成。

    可能描述得有些抽象,接下来用图一步一步的示意:

    将数组第一个数23赋给temp变量,指针 i 指向数组第一个元素,指针 j 指向数组最后一个元素

    从 j 开始遍历(从右往左),遇到13时,因为13<=temp,因此将arr[j]填入arr[i]中,即此时指针 i 指向的数为13;

     再从 i 遍历(从左往右),遇到45时,因为45>temp,因此将arr[i]填入arr[j]中,此时指针 j 指向的数为45;

     继续从 j 遍历,遇到11时,因为11<=temp,因此将arr[j]填入arr[i]中,即此时指针 i 指向的数为11;

    从 i 遍历,遇到89时,因为89>temp,因此将arr[i]填入arr[j]中,此时指针 j 指向的数为89;

     从 j 遍历,遇到17时,因为17<=temp,因此将arr[j]填入arr[i]中,即此时指针 i 指向的数为17;

    从 i 遍历,遇到72时,因为72>temp,因此将arr[i]填入arr[j]中,此时指针 j 指向的数为72;

    从 j 遍历,遇到3时,因为3<=temp,因此将arr[j]填入arr[i]中,即此时指针 i 指向的数为3;

    从 i 遍历,遇到26时,因为26>temp,因此将arr[i]填入arr[j]中,此时指针 j 指向的数为26;

     从 j 遍历,和 i 重合;

    将 temp(基准数23)填入arr[i]中。

     此时完成算法的第2个步骤,接下来将23左边和右边的子区间分别用以上方法进行排序,直到区间只有一个元素即排序完成。

     代码如下:

    // Quick_Sort.cpp : Defines the entry point for the application.
    // 快速排序算法
     
    #include "stdafx.h"
    #include<iostream>
    using namespace std;
     
    //快速排序算法(从小到大)
    //arr:需要排序的数组,begin:需要排序的区间左边界,end:需要排序的区间的右边界
    void quickSort(int *arr,int begin,int end)
    {
        //如果区间不只一个数
        if(begin < end)
        {
            int temp = arr[begin]; //将区间的第一个数作为基准数
            int i = begin; //从左到右进行查找时的“指针”,指示当前左位置
            int j = end; //从右到左进行查找时的“指针”,指示当前右位置
            //不重复遍历
            while(i < j)
            {
                //当右边的数大于基准数时,略过,继续向左查找
                //不满足条件时跳出循环,此时的j对应的元素是小于基准元素的
                while(i<j && arr[j] > temp)
                    j--;
                //将右边小于等于基准元素的数填入右边相应位置
                arr[i] = arr[j];
                //当左边的数小于等于基准数时,略过,继续向右查找
                //(重复的基准元素集合到左区间)
                //不满足条件时跳出循环,此时的i对应的元素是大于等于基准元素的
                while(i<j && arr[i] <= temp)
                    i++;
                //将左边大于基准元素的数填入左边相应位置
                arr[j] = arr[i];
            }
            //将基准元素填入相应位置
            arr[i] = temp;
            //此时的i即为基准元素的位置
            //对基准元素的左边子区间进行相似的快速排序
            quickSort(arr,begin,i-1);
            //对基准元素的右边子区间进行相似的快速排序
            quickSort(arr,i+1,end);
        }
        //如果区间只有一个数,则返回
        else
            return;
    }
    int main()
    {
        int num[12] = {23,45,17,11,13,89,72,26,3,17,11,13};
        int n = 12;
        quickSort(num,0,n-1);
        cout << "排序后的数组为:" << endl;
        for(int i=0;i<n;i++)
            cout << num[i] << ' ';
        cout << endl;
        system("pause");
        return 0;
    }

    运行结果如下:

  • 相关阅读:
    【Silverlight】汉诺塔游戏,带AI
    Farseer Physics Engine
    解决SilverLight的图片裁剪问题
    【C#】三维立体验证码 (3DCaptcha)
    又一个“众所周知”的DAL层设计BUG
    【C#】性别类
    36进制条码序列号生成器 [更新]
    理想的软件设计标准
    表驱动法概念到实战(一) 原理及基本运用
    Sudoku solver
  • 原文地址:https://www.cnblogs.com/fengyangcai/p/13772940.html
Copyright © 2011-2022 走看看