C#之ArraySort(一)

C#之ArraySort (一)

本文主要记录一下自己的学习过程,如有误,请指正

C#里的 Array.Sort 主要采用了 3 种排序算法,根据每种算法的特性,合理使用,达到更优。


1. 插入排序(InsertionSort)

插入排序在数据量少,且大多有序的情况下,效率不错。

  • 时间复杂度 :

    • best - case :O(n).
    • worst - case : O(n2).
  • wiki上的算法图解:


2. 快速排序(QuickSort)

快速排序,如其名字一样,它很快。

  • 基本思想

    采用分治思想,选区一个pivot作为基准,左边元素都小于它,右边则大与它,分割成两个区间。再按此方法进行分割,直到排序完成。

  • 时间复杂度 :

    • best - case : O(nlogn).
    • worst - case : O(n2).
    • avg - case : O(nlogn).
  • 算法图解 :

    1. 选取一个pivot作为基准,这里取最右边的元素。
    2. left指针右移,直到 T[left] >= pivot;right指针左移,直到T[right] <= pivot。
      交换 T[right] 、T[left]。
    3. 重复步骤 2,直到 left >= right。交换T[left]、 pivot。T[left]作为新基准,分割区间。
    4. 重复步骤2 步骤3
  • 优化:三数中值法

    对最左,最右,以及中间的元素进行排序,如红框所示,pivot-> M,right->红箭头。

    此外,还进行了一次额外交换,保证pivot的位置在右端,如蓝框所示,pivot值不变(仍然为5),位置改变,right->蓝箭头。

    细心的读者,参考源码后可能会发现,.net中Sort采用的递归方式与一些教科书的写法有一点差异。有兴趣的童鞋,可以自行研究。


3. 堆排序(HeapSort)

堆排利用了堆这种数据结构。

  • 堆的性质

    • 总是一颗完全二叉树
    • 大顶堆、小顶堆 满足任意一个。
      • 大顶堆,堆中节点的值 总大于或等于 其孩子节点的值。
      • 小顶堆,堆中节点的值 总小于或等于 其孩子节点的值。
  • 性质简析

    • 非叶节点个数 n = arr.Length / 2, 每个非叶节点元素则为 arr[n - 1], 其孩子节点则为 arr[2n - 1]、 arr[2n]。 当第n个节点 只有一个孩子时, arr[2n] 不存在
    • 大顶堆: arr[n - 1] >= arr[2n - 1] , arr[n - 1] >= arr[2n]
    • 小顶堆: arr[n - 1] <= arr[2n - 1] , arr[n - 1] <= arr[2n]
  • 基本思想

    构建大顶堆,交换首尾元素。断尾,重构大顶堆,再交换首尾元素。直到没有尾巴去断。

  • 时间复杂度:

    • any - case : O(nlogn).
  • 算法图解:

    • 无序堆和大根堆

    • 构建大根堆

    • 排序过程
    1. 构建大顶堆。从最后一个非叶节点arr[n - 1]开始。
      判断两个 孩节点 的大小,其中最大的孩节点 继续与 非叶节点比较,若大于,则交换。接着调整 arr[n -2],直到arr[0],即根节点。
    2. 交换首元素和末元素,去除末元素。
    3. 重构大顶堆,由于交换的是根节点,所以我们从 arr[0] 开始, 判断方法与 步骤 1 类似。但这里,由于是从根节点arr[0]开始的,所以需要执行到到最后一个非叶节点,即 arr[n - 1]。
    4. 重复 步骤2 步骤3 直到完成排序。

4. 简单测试

  • 测试条件
    模式: release
    次数:2k
    数组:随机数组,可重复,大小N(100,1000,5000,10000,100000,1000000)
    时间单位:s

  • 在这里插入图片描述

5. 全部代码

using System;
namespace Sort {
   
    public class Sorts<T> where T : IComparable<T> {
   
        
        #region  插排
        public static void InsertionSort (T[] keys, int l, int r) {
   
            
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值