zoukankan      html  css  js  c++  java
  • 算法导论之快速排序---学习笔记

        最近一直在看《算法导论》,看完麻省理工的视频,才敢动手敲敲代码。对于一些经典算法感觉看了就会忘 ,只有自己体会了消化了才会成为自己的东西,在这里就相当于写写笔记加深印象。快速排序是一种基于分治技术的排序算法,思想核心是选择一个基准元素X将待排序元素分成两个子序列,使得一个子序列中的元素均小于等于X,而另一个子序列中的元素均大于X,处于其终端所处在的位置上。

        或者你也可以打个比喻,想象一下,假设r为主元素,J元素为前方开路元素,和主元素进行比较,如果大于主元素则继续开路 ,如果小于主元素则I元素加1之后和J元素交换之后,J元素继续开路直到最后。

    书中给出了划分的伪代码:

    1 PARTITION(A,p,r)
    2    x = A[r]   //将最后一个元素作为主元素
    3   i = p-1
    4    for j=p to r-1     //从第一个元素开始到倒数第二个元素结束,比较确定主元的位置
    5        do if A[j] <= x
    6              i = i+1
    7              exchange A[i] <-> A[j]
    8    exchange A[i+1]<->A[r]   //最终确定主元的位置
    9    return i+1   //返回主元的位置

    通过递归,书中又给出了快速排序的伪代码:

    1 QUICKSORT(A,p,r)
    2     if p<r
    3        q = PARTITION(A,p,r)    //确定划分位置
    4        QUICKSORT(A,p,q-1)     //子数组A[p...q-1]
    5        QUICKSORT(Q,q+1,r)     //子数组A[q+1...r]

     采用C#语言来段代码:

      static void Main(string[] args)
            {
                int[] ArrInput = new int[] { 78, 13, 9, 23, 45, 14, 35, 65, 56, 79 };
    
    
                QuickSort(ArrInput, 0, ArrInput.Length - 1);
                for (int i = 0; i < ArrInput.Length; i++)
                {
                    Console.WriteLine(ArrInput[i]);
                }
                Console.Read();
            }
            /// <summary>
            /// 快速排序算法
            /// </summary>
            /// <param name="arr"></param>
            /// <param name="p"></param>
            /// <param name="q"></param>
            /// <returns></returns>
    
            static int Partition(int[] arr, int p, int q)
            {
                #region
                //根据算法导论上的来的    
                int x = arr[q];
                int i = p - 1;
                for (int j = p; j <= q - 1; j++)
                {
                    if (arr[j] <= x)
                    {
                        i=i+1;
                        Swap(arr, i,j);
                    }
                }
                Swap(arr, i+1,q);
                return (i + 1);
                #endregion
    
            }
            /// <summary>
            /// 递归实现左右两部分
            /// </summary>
            /// <param name="arr"></param>
            /// <param name="p"></param>
            /// <param name="r"></param>
            static void QuickSort(int[] arr, int p, int r)
            {
                if (p < r)
                {
                    int q = Partition(arr, p, r);
                    QuickSort(arr, p, q - 1);
                    QuickSort(arr, q + 1, r);
                }
            }
            /// <summary>
            /// 交换数据
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            static void Swap(int []a, int n1,int n2)
            {
                var temp = a[n1];
                a[n1]= a[n2];
               a[n2] = temp;
    
            }

       经过分析,快速排序算法在平均情况下的时间复杂度为T(N)=O(nlogn),如果序列本身已经是排好序了此时快速排序处于最坏的情况。可以通过修改操作Partition,采用随机选择策略来选择基准元素 。至于随机化快速排序大家可以参考其他的资料。

    热爱C++编程,自认为通过努力改变人生,喜欢研究新奇技术。
    转载请注明出处。 作者:曹麒文 
    博客地址:http://www.cnblogs.com/master-image/
  • 相关阅读:
    使用json-lib进行Java和JSON之间的转换
    PHP实现RabbitMQ消息队列(转)
    PHP错误日志和内存查看(转)
    linux下安装python3(转)
    如何在Linux上设置SSH密码以进行无密码登录(转)
    事务的ACID特性(转)
    PHP之缓存雪崩,及解决方法(转)
    php字符串统计次数的各种方法(转)
    php批量检测和去掉bom头(转)
    go延时队列
  • 原文地址:https://www.cnblogs.com/master-image/p/3187302.html
Copyright © 2011-2022 走看看