快速排序的分析与实现-创新互联

快速排序是一种使用性非常强的排序算法,虽然它最坏的情况下时间复杂度O(N^2),但平均时间复杂度是O(N*logN),并在内存的使用、程序算法的复杂性上表现优秀,尤其是对快速排序进行随机化的可能,快速排序是最使用的一种算法之一。

采用H5高端网站建设+css3国际标准网站建设,让网站自动适应用户使用终端设备,PC、平板、手机等,一个网址适应,一套内容统一战略,节约企业资源。创新互联还提供网站后期营销如:软文发稿友情链接一元广告等。一般建站公司不为企业填充资料,更谈不上内容策划,结果导致网站界面优秀,内容却十分空泛或整体不协调,内容策划、内容填充请交给我们。

 算法思想:

  1.创建一个临时变量,把数组中最右边的值保存起来,最右边就形成一个坑。

  2.然后找左边大于临时变量的那个值放到坑里,这样左边会形成新的坑。

  3.在找右边小于临时变量的那个值放到新的坑里,就这样一直找。

  4.知道找完,最后把临时变量放到最后形成的那个坑里。

  5.在把这个数组分成两个子序列,特点:左边的子序列中的数小于等于右边的子序列中的数。

  6.在通过递归调用,来排序子序列。

  5.知道子序列排完,然后合并。(由于子序列是就地序列,所以合并不需要操作,排序已经完成)

实现代码:

Sort.h中

int SingleSort(int *a, int left, int right)
{
    assert(a);
  int tmp = a[right];//临时变量保存值
        while (left < right)
     {
           //找左边大于等于tmp的数
              while (left < right&&tmp >= a[left])
          {
                   left++;
             }
           if (left < right)
                {
                   a[right--] = a[left];//把值给右边,然后--
           }
           //找右边小于等于tmp的值
              while (left < right&&tmp <= a[right])
         {
                   right--;
            }
           if (left < right)
                {
                   a[left++] = a[right];//把值给左边,然后++
           }
   }
   a[left] = tmp;
      return left;
}
void QuickSort(int *arr, int left, int right)
{
     if (arr == NULL)
    {
           return;
     }
   if (left < right)
        {
           //递归调用
              int div = SingleSort(arr, left, right);
             QuickSort(arr, left, div - 1);
              QuickSort(arr, div + 1, right);
     }
}
//打印函数
void Print(int *arr, int size)
{
     for (int i = 0; i < size; i++)
   {
           cout << arr[i] << " ";
  }
   cout << endl;
}

test.cpp中

#include
using namespace std;
#include "Sort.h"

void Test()
{
  int arr[] = { 3, 9, 7, 6, 1, 2, 4, 8, 0, 5 };
       QuickSort(arr, 0,sizeof(arr) / sizeof(arr[0])-1);
   Print(arr, sizeof(arr) / sizeof(arr[0]));
}
int main()
{
   Test();
     system("pause");
    return 0;
}

 我曾经看过看过一篇博客,快速排序对小范围数字排序会花费很多时间,通过我查询资料得知,数字总量小于13,用直接插入排序表较好,超过这个数字用快速排序。然后我就把代码改了一下.

//直接插入排序
void InsertSort(int *a, int size)
{
        int end;
    int tmp;
    for (int i = 0; i < size - 1; i++)
       {
           end = i;
            tmp = a[end + 1];
           while (end >= 0 && tmp

  上面的代码还不够好,如果快速排序是,你的运气比较差,每次取出的数都是大或者最小,这样的话他就会变成最坏一种情况,时间复杂度为O(N^2),为了避免这种情况,我想到一种办法,三数取中法,

它是什么意思?

  三个数分别为最左边,最右边,中间这三个数,取得话,就取既不是大也不是最小的这个数,这样就能避免上面那种情况。

//三数取中
int Mid(int *a, int left, int right)
{
        int mid = left - (left - right);
    if (a[left] < a[right])
  {
           if (a[left]>a[mid])
              {
                   return a[left];
             }
           else if (a[right] < a[mid])
              {
                   return a[right];
            }
           else
                {
                   return a[mid];
              }
   }
   else
        {
           if (a[right] > a[mid])
           {
                   return a[right];
            }
           else if (a[left] < a[mid])
               {
                   return a[left];
             }
           else
                {
                   return a[mid];
              }
   }
}
int SingleSort(int *a, int left, int right)
{
  assert(a);
  int tmp = Mid(a,left,right);//临时变量保存值,三数取中
  while (left < right)
     {
           //找左边大于等于tmp的数
              while (left < right&&tmp >= a[left])
          {
                   left++;
             }
           if (left < right)
                {
                   a[right--] = a[left];//把值给右边,然后--
           }
           //找右边小于等于tmp的值
              while (left < right&&tmp <= a[right])
         {
                   right--;
            }
           if (left < right)
                {
                   a[left++] = a[right];//把值给左边,然后++
           }
   }
   a[left] = tmp;
      return left;
}

这样就比较完善了,如果我不想用递归,该这么办那?然后我就想到了借助栈来实现。

void QuickSort(int *arr, int left, int right)
{
   stack s;
 s.push(left);//压栈数组的左下标
     s.push(right);//压栈数组的有下标
    while (!s.empty())
  {
           int tmpRight = s.top();
             s.pop();
            int tmpLeft = s.top();
              s.pop();
            //把数组排序成左区间的数小于等于有区间的数
              int div = SingleSort(arr, tmpLeft, tmpRight);
               //压栈左区间的左右两个数的下标
            if (tmpLeft < div - 1)
           {
                   s.push(tmpLeft);
                    s.push(div - 1);
            }
           //压栈右区间的左右两个数的下标
             if (div + 1 < tmpRight)
         {
                   s.push(div + 1);
                    s.push(tmpRight);
           }
   }
}

 写到这里,我有想到了另一种实现SingleSort()函数的方法,感觉比上面的更简单,不过理解起来比较抽象。

  思想:

   1.定义一个cur为a[0]位置的下标

   2.在定义一个prev为a[0]的前一个位置。

   3.当a[0]位置的值小于最右边的值。

   4.++prev,然后交换prev和cur对应的值。

   5.如果小于最右边的值,++prev,prev和最右边值交换。

   6.一直进行下去,就会让左边的值小于等于右边的值。

int SingleSort(int *arr, int left, int right)
{
       int cur = left;
     int prev = cur - 1;
 int key = Mid(arr, left, right);
    swap(arr[right], key);//把key的值放到最右边
 while (cur < right)
      {
           //++prev != cur防止自己和自己交换
            if (arr[cur]<=arr[right]&&++prev != cur)
         {
                   swap(arr[prev], arr[cur]);
          }
           cur++;
      }
   swap(arr[++prev], arr[right]);
      return prev;
}

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


网站标题:快速排序的分析与实现-创新互联
转载注明:http://myzitong.com/article/epgdh.html