原理
1.选出一个基准值 (默认数组开始位置)
2.从数组尾开始遍历查找 找是否有比基准值小的数 有就记录下来停止遍历(注意这里是从尾开始遍历 因为默认基准值取的是开头 保证基准值左边一定比基准值小)
3.再从数组头开始遍历查找 找是否有比基准值大的数 有就记录下来 停止遍历
4. 交换找到的 两个位置 这两次查找就实现了一次 左右交换 保证了 基准值左边的数 起码有一个是小的 基准值右边 起码有一个数是大的
5. 不断重复 知道左右遍历的指针相等了 说明这轮所有交换完毕
6. 重合的位置 就是新基准值的位置 把他重新赋值一下,返回当前重合的指针位置 即 左指针或者是右指针
7. 开始递归 有了中间基准值位置之后 开始分为左右两边
左边是 【数组开始位置 ,基准值下标 -1】
右边是 【基准值下标 + 1, 数组结束位置】
8. 递归跳出条件 就是 开始位置 >= 结束位置
废话不多说 代码部分
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FastSort : MonoBehaviour
{
public int[] datas;
void Start()
{
datas = new int[] { 12,2,43,3,8,10,5,5,11,0};
}
[ContextMenu("term test FaskSort")]
public void Test()
{
FastSortData(datas, 0, datas.Length - 1);
}
public void SwapData(ref int a, ref int b)
{
//交换两个数据 ref 可以 关联引用 而不是单独的值
int temp = b;
b = a;
a = temp;
}
public void FastSortData(int[] datas,int startIndex, int endIndex)
{
if(startIndex >= endIndex)
{
//当左右指针重合 退出递归
return;
}
int midIndex = GetMidIndexAndSortOne(datas, startIndex, endIndex);
FastSortData(datas, startIndex, midIndex - 1); //注意这里是 midIndex - 1 因为midIndex 位置已经固定了
FastSortData(datas, midIndex + 1, endIndex);
}
public int GetMidIndexAndSortOne(int[] datas, int startIndex, int endIndex)
{
//排序一次 用第一个作为基准值 比基准值小的在左边 大的在右边
int targetValue = datas[startIndex];
int leftIndex = startIndex;
int rightIndex = endIndex;
while(true)
{
if(leftIndex >= rightIndex)
{
//跳出循环 当指针遍历到重合的时候 代表这一轮基准值判断已经结束
break;
}
while(true)
{
if(leftIndex >= rightIndex || datas[rightIndex] < targetValue)
{
//移动到尽头了 退出循环 或者 右边指针向左移动 找到一个比基准值小的
break;
}
rightIndex = rightIndex - 1;
}
while(true)
{
if (leftIndex >= rightIndex || datas[leftIndex] > targetValue)
{
//移动到尽头了 退出循环 或者 左边指针向右移动 找到一个比基准值大的
break;
}
leftIndex = leftIndex + 1;
}
//交换 左边和右边找到的 一个大 一个小的值
SwapData(ref datas[leftIndex], ref datas[rightIndex]);
}
//全都遍历完了 那么两个指针肯定就重合了 重合的位置就是 基准值的位置 把基准值赋值过去
SwapData(ref datas[startIndex], ref datas[leftIndex]);
return leftIndex;
}
}
实际效果
排序前:
排序后