算法导论实践——快速排序

算法导论实践——快速排序

在学习算法导论之前,一直对快速排序有很大的畏惧感。还记得当时教我们数据结构的老师就硬给我们讲一堆算法,其中快速排序是真的叫我头疼。当时的感觉就是 我只看到了第一层,老师却在第五层

理论

  • 分解:依据一个关键值(Pivot),把原数组分解成为两个子数组。其中一个子数组全部元素小于等于Pivot(后文称小数组)在Pivot前面;另外一个全部大于等于Pivot(后文称大数组),在Pivot后面。
  • 解决:对两个子数组进行递归操作。
  • 合并:因为我们是对原本的数组进行排序,(所谓原址排序),所以并不需要合并操作。

其中,分解操作很重要,算是算法的核心,算法导论给了我们一张图来诠释分解操作,我认为这幅图真的非常好。
快速排序的分解步骤
下面,来诠释一下变量,自然就很好理解了。

  • p,r :分别为数组的最小下标和最大下标
  • 选择Pivot为A[r],也就是最后一个元素,图中为4
  • i:小数组的最大下标,可以发现 i - p + 1 就是小数组的长度,因此,我把它称为一种小数组的相对长度
  • j:大数组的最大下标,j - i - 1 就是大数组的长度,同理,我把它称为大数组的相对长度

容易发现,浅色区域的值都小于Pivot,深色区域的值都大于Pivot,最后,将Pivot与A[i+1]换一个位置,就能够知道数组该从哪个位置划分为两个数组了。

下面直接上代码。

C# 实现

FastSortUtil

using System;
using System.Collections.Generic;
using System.Text;

namespace Sort
{
    public static class FastSortUtil
    {
    	//快排函数
        public static void FastSort(int [] A, int p, int r)
        {
            if (p < r)
            {
                int q = Partition(A, p, r); //得到Pivot所在位置下标
                FastSort(A, p, q - 1);//对小数组递归快排
                FastSort(A, q + 1, r);//对大数组递归快排
            }
        }

		//分解步骤
        private static int Partition(int[] A, int p, int r)
        {
            int pivot = A[r];//将数组最后一个元素作为Pivot
            int i = p - 1;//i作为小数组最大下标
            for(int j = p; j <= r - 1; j++)//j作为大数组最大下标
            {
            	//发现A[j]不满足大数组条件,说明A[j]应该属于小数组
                if (A[j] <= pivot)
                {
                    i++;//小数组最大下标(相对长度)+1,用于承载A[j]。
                    Swap(A, i, j);//交换A[i]和A[j]
                }
            }
            Swap(A, i + 1, r);//最后交换Pivot和A[i+1]
            return i + 1;//返回Pivot当前的位置下标
        }
		
		//交换元素
        private static void Swap(int[]A,int p, int q)
        {
            var mid = A[p];
            A[p] = A[q];
            A[q] = mid;
        }
		
		//输出结果
        public static void GetResult(int[] A)
        {
            for(int i = 0; i < A.Length; i++)
            {
                Console.Write(A[i]);
                Console.Write("  ");
            }
        }
    }
}

Program

using System;
using Sort;

namespace Sort
{
    class Program
    {
        static void Main(string[] args)
        {
        //在主函数调用即可
            int[] A = { 1, 5, 6, 7, 1, 2, 3, 4 };
            FastSortUtil.FastSort(A, 0, A.Length - 1);
            FastSortUtil.GetResult(A);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值