栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

C# 十种排序方法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C# 十种排序方法

using System;
using System.Collections.Generic;
using UnityEngine;

/// 
/// 排序逻辑控制器
/// 
public class SortController : MonoBehaviour
{
    private static SortController _instance;

    public static SortController GetInstance()
    {
        return _instance;
    }

    void Awake()
    {
        if (_instance == null)
        {
            _instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            if (_instance != this)
            {
                Debug.Log("warning: multiple Manager creating!");
                GameObject.Destroy(gameObject);
            }
        }
    }

    #region 选择排序

    /// 
    /// 选择排序
    /// 
    /// 需要排序的数组值
    /// 
    public int[] SelectSort(int[] arr)
    {
        int n = arr.Length;
        for (int i = 0; i < n - 1; i++)
        {
            int min = i;
            for (int j = i + 1; j < n; j++)
            {
                if (arr[min] > arr[j]) min = j;
            }

            //交换
            int temp = arr[i];
            arr[i] = arr[min];
            arr[min] = temp;
        }

        return arr;
    }

    #endregion

    #region 插入排序

    /// 
    /// 插入排序
    /// 
    /// 需要排序的数组值
    /// 
    public int[] InsertSort(int[] arr)
    {
        if (arr == null || arr.Length < 2)
            return arr;

        int n = arr.Length;
        for (int i = 1; i < n; i++)
        {
            int temp = arr[i];
            int k = i - 1;
            while (k >= 0 && arr[k] > temp)
                k--;
            //腾出位置插进去,要插的位置是 k + 1;
            for (int j = i; j > k + 1; j--)
                arr[j] = arr[j - 1];
            //插进去
            arr[k + 1] = temp;
        }

        return arr;
    }

    #endregion

    #region 冒泡排序

    /// 
    /// 冒泡排序
    /// 
    /// 需要排序的数组值
    /// 
    public int[] BubbleSort(int[] arr)
    {
        if (arr == null || arr.Length < 2)
        {
            return arr;
        }

        int n = arr.Length;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n - i - 1; j++)
            {
                if (arr[j + 1] < arr[j])
                {
                    int t = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = t;
                }
            }
        }

        return arr;
    }

    #endregion

    #region 希尔排序

    /// 
    /// 希尔排序
    /// 
    /// 需要排序的数组值
    /// 
    public int[] ShellSort(int[] arr)
    {
        if (arr == null || arr.Length < 2) return arr;
        int n = arr.Length;
        // 对每组间隔为 h的分组进行排序,刚开始 h = n / 2;
        for (int h = n / 2; h > 0; h /= 2)
        {
            //对各个局部分组进行插入排序
            for (int i = h; i < n; i++)
            {
                // 将arr[i] 插入到所在分组的正确位置上
                InsertIValue(arr, h, i);
            }
        }

        return arr;
    }

    /// 
    /// 将arr[i]插入到所在分组的正确位置上,arr[i]] 所在的分组为 ... arr[i-2*h],arr[i-h], arr[i+h] ...
    /// 
    /// 
    /// 
    /// 
    private void InsertIValue(int[] arr, int h, int i)
    {
        int temp = arr[i];
        int k;
        for (k = i - h; k > 0 && temp < arr[k]; k -= h)
        {
            arr[k + h] = arr[k];
        }

        arr[k + h] = temp;
    }

    #endregion

    #region 归并排序

    /// 
    /// 归并排序(递归式)
    /// 
    /// 需要排序的数组值
    /// 左半部分索引
    /// 右半部分索引
    /// 
    public int[] MergeSort(int[] arr, int left, int right)
    {
        // 如果 left == right,表示数组只有一个元素,则不用递归排序
        if (left < right)
        {
            // 把大的数组分隔成两个数组
            int mid = (left + right) / 2;
            // 对左半部分进行排序
            arr = MergeSort(arr, left, mid);
            // 对右半部分进行排序
            arr = MergeSort(arr, mid + 1, right);
            //进行合并
            Merge(arr, left, mid, right);
        }

        return arr;
    }

    /// 
    /// 归并排序(非递归式)
    /// 
    /// 
    /// 
    public int[] MergeNonFuncSort(int[] arr)
    {
        int n = arr.Length;
        //子数组的大小分别为1,2,4,8...,合并的数组大小是1,接着是2,接着4...
        for (int i = 1; i < n; i += i)
        {
            //进行数组进行划分
            int left = 0;
            int mid = left + i - 1;
            int right = mid + i;
            //进行合并,对数组大小为 i 的数组进行两两合并
            while (right < n)
            {
                //合并函数和递归式的合并函数一样
                Merge(arr, left, mid, right);
                left = right + 1;
                mid = left + i - 1;
                right = mid + i;
            }

            // 剩余数组合并
            if (left < n && mid < n)
            {
                Merge(arr, left, mid, n - 1);
            }
        }

        return arr;
    }

    /// 
    /// 合并函数,把两个有序的数组合并起来。arr[left..mif]表示一个数组,arr[mid+1 .. right]表示一个数组
    /// 
    /// 
    /// 
    /// 
    /// 
    private void Merge(int[] arr, int left, int mid, int right)
    {
        //临时数组进行合并汇总
        int[] a = new int[right - left + 1];
        int i = left;
        int j = mid + 1;
        int k = 0;
        while (i <= mid && j <= right)
        {
            if (arr[i] < arr[j])
            {
                a[k++] = arr[i++];
            }
            else
            {
                a[k++] = arr[j++];
            }
        }

        while (i <= mid) a[k++] = arr[i++];
        while (j <= right) a[k++] = arr[j++];
        //临时数组复制到原数组
        for (i = 0; i < k; i++)
        {
            arr[left++] = a[i];
        }
    }

    #endregion

    #region 快速排序

    /// 
    /// 快速排序
    /// 
    /// 需要排序的数组值
    /// 
    /// 
    /// 
    public int[] QuickSort(int[] arr, int left, int right)
    {
        if (left < right)
        {
            //获取中轴元素所处的位置
            int mid = PartPosition(arr, left, right);
            //进行分割
            arr = QuickSort(arr, left, mid - 1);
            arr = QuickSort(arr, mid + 1, right);
        }

        return arr;
    }

    /// 
    /// 获取中轴元素所处的位置
    /// 
    /// 
    /// 
    /// 
    /// 
    private int PartPosition(int[] arr, int left, int right)
    {
        //选取中轴元素
        int pivot = arr[left];
        int i = left + 1;
        int j = right;
        while (true)
        {
            // 向右找到第一个小于等于 pivot 的元素位置
            while (i <= j && arr[i] <= pivot) i++;
            // 向左找到第一个大于等于 pivot 的元素位置
            while (i <= j && arr[j] >= pivot) j--;
            if (i >= j)
                break;
            //交换两个元素的位置,使得左边的元素不大于pivot,右边的不小于pivot
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

        arr[left] = arr[j];
        // 使中轴元素处于有序的位置
        arr[j] = pivot;
        return j;
    }

    #endregion

    #region 堆排序

    /// 
    /// 堆排序
    /// 
    /// 
    /// 
    public int[] HeadSort(int[] arr)
    {
        int n = arr.Length;
        //构建大顶堆
        for (int i = (n - 2) / 2; i >= 0; i--)
        {
            DownAdjust(arr, i, n - 1);
        }

        //进行堆排序
        for (int i = n - 1; i >= 1; i--)
        {
            // 把堆顶元素与最后一个元素交换
            int temp = arr[i];
            arr[i] = arr[0];
            arr[0] = temp;
            // 把打乱的堆进行调整,恢复堆的特性
            DownAdjust(arr, 0, i - 1);
        }

        return arr;
    }

    /// 
    /// 下沉操作
    /// 
    /// 
    /// 
    /// 
    public void DownAdjust(int[] arr, int parent, int n)
    {
        //临时保存要下沉的元素
        int temp = arr[parent];
        //定位左孩子节点的位置
        int child = 2 * parent + 1;
        //开始下沉
        while (child <= n)
        {
            // 如果右孩子节点比左孩子大,则定位到右孩子
            if (child + 1 <= n && arr[child] < arr[child + 1])
                child++;
            // 如果孩子节点小于或等于父节点,则下沉结束
            if (arr[child] <= temp) break;
            // 父节点进行下沉
            arr[parent] = arr[child];
            parent = child;
            child = 2 * parent + 1;
        }

        arr[parent] = temp;
    }

    #endregion

    #region 计算排序

    /// 
    /// 计算排序
    /// 
    /// 
    /// 
    public int[] CountSort(int[] arr)
    {
        if (arr == null || arr.Length < 2) return arr;

        int n = arr.Length;
        int min = arr[0];
        int max = arr[0];
        // 寻找数组的最大值与最小值
        for (int i = 1; i < n; i++)
        {
            if (max < arr[i])
                max = arr[i];
            if (min > arr[i])
                min = arr[i];
        }

        int d = max - min + 1;
        //创建大小为max的临时数组
        int[] temp = new int[d];
        //统计元素i出现的次数
        for (int i = 0; i < n; i++)
        {
            temp[arr[i] - min]++;
        }

        int k = 0;
        //把临时数组统计好的数据汇总到原数组
        for (int i = 0; i < d; i++)
        {
            for (int j = temp[i]; j > 0; j--)
            {
                arr[k++] = i + min;
            }
        }

        return arr;
    }

    #endregion

    #region 桶排序

    /// 
    /// 桶排序
    /// 
    /// 
    /// 
    public double[] BucketSort(double[] arr, int bucketNum)
    {
        //创建bucket时,在二维中增加一组标识位,其中bucket[x, 0]表示这一维所包含的数字的个数
        //通过这样的技巧可以少写很多代码
        double[,] bucket = new double[bucketNum, arr.Length + 1];
        foreach (var num in arr)
        {
            int bit = (int) (bucketNum * num);
            bucket[bit, (int) ++bucket[bit, 0]] = num;
        }

        //为桶里的每一行使用插入排序
        for (int j = 0; j < bucketNum; j++)
        {
            //为桶里的行创建新的数组后使用插入排序
            double[] insertion = new double[(int) bucket[j, 0]];
            for (int k = 0; k < insertion.Length; k++)
            {
                insertion[k] = bucket[j, k + 1];
            }

            //调用插入排序
            StraightInsertionSort(insertion);
            //把排好序的结果回写到桶里
            for (int k = 0; k < insertion.Length; k++)
            {
                bucket[j, k + 1] = insertion[k];
            }
        }

        //将所有桶里的数据回写到原数组中
        for (int count = 0, j = 0; j < bucketNum; j++)
        {
            for (int k = 1; k <= bucket[j, 0]; k++)
            {
                arr[count++] = bucket[j, k];
            }
        }

        return arr;
    }

    private void StraightInsertionSort(double[] array)
    {
        //插入排序
        for (int i = 1; i < array.Length; i++)
        {
            double sentinel = array[i];
            int j = i - 1;
            while (j >= 0 && sentinel < array[j])
            {
                array[j + 1] = array[j];
                j--;
            }

            array[j + 1] = sentinel;
        }
    }

    #endregion

    #region 基数排序

    /// 
    /// 基数排序
    /// 
    /// 
    /// 
    public int[] RandixSort(int[] myArray, int keyNum)
    {
        SingleLinkedList listArray = new SingleLinkedList();
        foreach (int i in myArray)
        {
            listArray.AddLast(new SingleLLNode() {Value = i});
        }

        for (int i = 0; i < keyNum; i++)
        {
            // 对每个关键字执行分配和收集操作
            DistributeAndCollect(listArray, i);
        }

        int j = 0;
        while (listArray.First != null)
        {
            myArray[j++] = listArray.First.Value;
            listArray.First = listArray.First.Next;
        }

        return myArray;
    }

    /// 
    /// 分配和收集
    /// 
    /// 
    /// 
    private void DistributeAndCollect(SingleLinkedList listArray, int i)
    {
        int randix = 10; //关键字取值范围
        int divider = (int) Math.Pow(10, i);
        List> subLists = new List>(); //建立子序列
        for (int j = 0; j < randix; j++)
        {
            subLists.Add(new SingleLinkedList());
        }

        // 开始一次分配
        while (listArray.First != null)
        {
            int index = (listArray.First.Value / divider) % 10;

            SingleLLNode tempNode = listArray.First.Next;
            subLists[index].AddLast(listArray.First);
            listArray.First = tempNode;
        }

        // 开始一次收集
        int k = 0;
        for (; k < randix; k++)
        {
            if (subLists[k].First != null)
            {
                // 找到第一个非空子序列以设置总序列的First值
                listArray.First = subLists[k].First;
                listArray.Last = subLists[k].Last;
                break;
            }
        }

        // 找好子序列设置好listArray.First后,开始处理非空子序列的首尾相连
        for (; k < randix; k++)
        {
            if (subLists[k].First != null)
            {
                listArray.Last.Next = subLists[k].First;
                listArray.Last = subLists[k].Last;
            }
        }
    }

    #endregion
}

// 单链表
class SingleLinkedList
{
    public SingleLLNode First { get; set; }

    public SingleLLNode Last { get; set; }

    public void AddLast(SingleLLNode node)
    {
        if (First == null)
        {
            First = node;
            Last = node;
            node.Next = null;
        }
        else
        {
            Last.Next = node;
            Last = node;
            node.Next = null;
        }
    }
}

// 单链表结点
class SingleLLNode
{
    public T Value { get; set; }

    public SingleLLNode Next { get; set; }
}

转载:https://developer.unity.cn/projects/61c307dfedbc2a001f3bb4b7

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/944928.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号