快速排序原理 C# 递归

快速排序原理 C# 递归

快速排序是一种二分法排序方法,实际上理论上真正最快的排序方法是黄金分割法,但是这在计算机上是很难实现的,因此快速排序也算是兼顾了速度与占用内存的一种较好的排序方式:
快速排序的实现步骤大概如下:

【假设我们需要将一个数组按照从小到大的顺序排列】

1、选最左侧的数作为一个基准数,并从左–>右从右–>左 分别寻找比基准数大 和 比基准数小的数,一定是先从右边先找,这是因为我们选择的是最左侧的数作为基准数,最后要将这个数放到最中间,而如果先从左边找,那么当左右相遇时候就可能出现中间数实际上比最左边的基准数大,这样就出BUG了,因此一定是先从右边寻找,然后找到一个小于基准数时就停下来,这时候,再从左边开始寻找,然后当找一个比基准数大的数就停下来,一直这样,直到左右寻找相遇。相遇时就将这个相遇点的数和第一个基准数交换。
2、经过了第一步就将数组分成了 2 份,相遇点左边一份 ,相遇点右边一份,然后在对着两部分重复第一步…
3、最后,当分到每一小份左右只有一个数的时候就完成了快速排序。

其中第二步涉及到递归过程,当然也是很好理解的,只要这个过程类似并且是具有递进关系的都可以用递归
就像切蛋糕一样,先一分为二,再一分为二,再一分为二,切的这个过程就是一个类似的过程,而越分越小就是一个递进的关系。

快速排序的时间复杂度为:O(N*log(N))

下面贴出代码,这样理解更容易:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FastSort
{
    class Program
    {
        static double[] RequireSortNum;
        static void Main(string[] args)
        {

            NumInit();
            Console.WriteLine("初始数据:");
            ShowCurrentSort();
            FastSort(0, 99);
            Console.WriteLine("快排序后数据:");
            ShowCurrentSort();
            Console.Read();
        }

        static void FastSort(int LeftIndex,int RightIndex)
        {
            if (LeftIndex > RightIndex)
                return;
            double BaseNum = RequireSortNum[LeftIndex];//将第一个点假设为基准点
            int CurrentRightIndex = RightIndex;//当前询问的右侧坐标
            int CurrentLeftIndex = LeftIndex;//当前询问的左侧坐标
            double temp;//交换的暂存值
            while (CurrentRightIndex != CurrentLeftIndex)//已知要询到左右两边相遇 这时候相遇点就是基准点的位置
            {
                while (RequireSortNum[CurrentRightIndex] >= BaseNum && CurrentRightIndex > CurrentLeftIndex)
                {
                    CurrentRightIndex--;
                }
                while (RequireSortNum[CurrentLeftIndex] < BaseNum && CurrentRightIndex > CurrentLeftIndex)
                {
                    CurrentLeftIndex++;
                }
                if (CurrentRightIndex > CurrentLeftIndex)//如果两边没有相遇就交换
                {
                    temp = RequireSortNum[CurrentRightIndex];
                    RequireSortNum[CurrentRightIndex] = RequireSortNum[CurrentLeftIndex];
                    RequireSortNum[CurrentLeftIndex] = temp;
                }                
            }
            //当两边相遇了 就将第一个基准点 放到中间位置
            RequireSortNum[LeftIndex] = RequireSortNum[CurrentRightIndex];
            RequireSortNum[CurrentRightIndex] = BaseNum;//将第一个点【这个点就是基准点】 放到中间位置
            //这是因为一开始是先从右边开始轮询的,最左边的被选做基准点的数并没有到正确的中间位置
            //这一步正是让这个点到它该去的位置
            FastSort(LeftIndex,CurrentLeftIndex-1);//排列中间点左侧的数据
            FastSort(CurrentRightIndex+1, RightIndex);//排列中间点右侧的数据
        }

        static void NumInit()
        {
            RequireSortNum = new double[100];
            Random rand = new Random();
            for(int a = 0;a < 100;a++)
                RequireSortNum[a] = 100 * rand.NextDouble();
        }

        static void ShowCurrentSort()
        {
            foreach (double item in RequireSortNum)
                Console.WriteLine(item.ToString("f0"));
            Console.Write("\n\n\n");
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值