zoukankan      html  css  js  c++  java
  • 排序算法

    常用的排序算法:

    public class Test : MonoBehaviour {
        void Swap(int[] arr, int i, int j)
        {
            int temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
        }
    
        /// <summary>
        /// 冒泡排序,遍历所有的数据,每次对相邻元素进行两两比较,如果顺序和预先规定的顺序不一致,则进行位置交换;
        /// 这样一次遍历会将最大或最小的数据上浮到顶端,之后再重复同样的操作,直到所有的数据有序。
        /// 有序序列[len - i,len],未排序序列[0,i]
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="len"></param>
        void BubbleSort(int[] arr, int len)
        {
            for (int i = 0; i < len; i++)
            {
                for (int j = 0; j < len - 1 - i; j++)
                {
                    if (arr[j] > arr[j + 1])
                    {
                        Swap(arr, j, j + 1);
                    }
                }
            }
        }
    
        /// <summary>
        /// 选择排序,每次从未排序的数据中寻找最大或最小的元素,依次放到排序序列中,直到所有数据样本排序完成
        /// 有序序列[0,i-1],未排序序列[i,len]
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="len"></param>
        void SelectSort(int[] arr, int len)
        {
            for (int i = 0; i < len; i++)
            {
                int min = i;
                for (int j = i + 1; j < len; j++)
                {
                    if (arr[min] < arr[j])
                    {
                        min = j;
                    }
                }
    
                Swap(arr, i, min);
            }
        }
    
        /// <summary>
        /// 插入排序,先将待排序序列的第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列;
        /// 然后从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置,直到所有数据都完成排序;
        /// 如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。
        /// 有序序列[0,i-1],未排序序列[i,len]
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="len"></param>
        void InsertSort(int[] arr, int len)
        {
            for (int i = 1; i < len; i++)
            {
                for (int j = i - 1; j > 0; j--)
                {
                    if (arr[i] < arr[j])
                    {
                        Swap(arr, i, j);
                    }
                    else
                        break;
                }
            }
        }
    
        /// <summary>
        /// 希尔排序,插入排序的一种改进版本,先将整个数据序列分割成若干子序列分别进行直接插入排序,(grap)
        /// 待整个序列中的记录基本有序时,再对全部数据进行依次直接插入排序。
        /// 有序序列[i,i+grap, i+grap+grap,....],未排序序列[0,grap]
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="len"></param>
        void ShellSort(int[] arr, int len)
        {
            int grap = len / 2;
            while (grap > 0)
            {
                for (int i = grap; i < len; i++)
                {
                    for (int j = i - grap; j >= 0; j -= grap)
                    {
                        if (arr[j] < arr[j - grap])
                        {
                            Swap(arr, j, j - grap);
                        }
                    }
                }
                grap /= 2;
            }
        }
    
        /// <summary>
        /// 快速排序,首先从数列中挑出一个元素,并将这个元素称为「基准。
        /// 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。
        /// 在这个分区结束之后,该基准就处于数列的中间位置。
        /// 之后,在子序列中继续重复这个方法,直到最后整个数据序列排序完成。
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="len"></param>
        void QuickSort(int[] arr, int left, int right)
        {
            if (left >= right) return;
    
            int bound = arr[right];
            int end = right;
            int start = left;
            right -= 1;
    
            while (left < right)
            {
                while (arr[left] > bound && left < right)
                {
                    left += 1;
                }
    
                while (arr[right] < bound && left < right)
                {
                    right -= 1;
                }
    
                Swap(arr, left, right);
            }
    
            if (arr[left] > bound)
            {
                Swap(arr, left, end);
            }
            else {
                left++;
            }
    
            QuickSort(arr, start, left - 1);
            QuickSort(arr, right + 1, end);
        }
    
        /// <summary>
        /// 归并排序,先将数据样本拆分为n个子数据样本(长度为1), 并分别对它们排序, 最后再将n个子数据样本合并在一起; 
        /// 
        /// </summary>
        /// <param name="arr"></param
        /// <param name="temp"></param>长度为len的空数组
        /// <param name="len"></param>
        void MergeSort(int[] arr, int[] temp, int start, int end)
        {
            if (start >= end) { return; }
    
            int len = end - start;
            int mid = len / 2;
    
            MergeSort(arr, temp, start, mid);
            MergeSort(arr, temp, mid, end);
    
            int start1 = start;
            int k = start;
            int end1 = mid + 1;
            while (start1 <= mid && end1 <= end)
            {
                if (arr[start1] < arr[end1])
                {
                    temp[k++] = arr[end1];
                    end1++;
                }
                else
                {
                    temp[k++] = arr[start1];
                    start1++;
                }
            }
    
            while (start1 <= mid)
            {
                temp[k++] = arr[start1];
            }
    
            while (end1 <= end)
            {
                temp[k++] = arr[end1];
            }
    
            for (k = start; k <= end; k++)
            {
                arr[k] = temp[k];
            }
        }
    
        /// <summary>
        /// 计数排序,使用一个额外的数组temp,其中temp[i]是待排序数组arr中值等于i的元素的个数。然后根据数组其中temp来将arr中的元素排到正确的位置。
        /// 数组第i个数据arr[i]因该放在temp[arr[i]]位置上
        /// 找出待排序的数组中最大和最小的元素
        ///统计数组中每个值为i的元素出现的次数,存入数组temp的第i项
        ///对所有的计数累加, 从temp中的第一个元素开始,每一项和前一项相加
        ///反向填充目标数组, 将每个元素i放在新数组的第temp[i]项,每放一个元素就将temp[i] 减去1
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="len"></param>
        /// <param name="max"></param>
        void CountSort(int[] arr, int len, int max)
        {
            int[] temp = new int[max];
            for (int i = 0; i < max; i++)
            {
                temp[i] = 0;
            }
    
            for (int i = 0; i < len; i++)
            {
                temp[arr[i]] += 1;
            }
    
            for (int i = 1; i < max; i++)
            {
                temp[i] += temp[i - 1];
            }
    
            int[] sort = new int[len];
            for (int i = 0; i < len; i++)
            {
                temp[arr[i]] -= 1;//数组0开始,所以先减
                sort[temp[arr[i]]] = arr[i];//数组第i个数据arr[i]因该放在temp[arr[i]]位置上          
            }
    
            for (int i = 0; i < len; i++)
            {
                arr[i] = sort[i];
            }
        }
    
        /// <summary>
        /// 基数排序,整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。
        /// 从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
        /// 例如先排序个位,在排序十位,一次类推。位数排序使用的是计数排序,即位数d的循环嵌套了一层计数排序
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="len"></param>
        void RadixSort(int[] arr, int len)
        {
            int maxBit = GetMaxBit(arr, len);
            int[] temp = new int[len];
            int[] numCount = new int[10];
            int curBit = 1;
    
            for (int i = 0; i < maxBit; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    numCount[j] = 0;
                }
    
                for (int k = 0; k < len; k++)
                {
                    int num = (arr[k] / curBit) % 10;
                    numCount[num] += 1;
                }
    
                for (int k = 1; k < 10; k++)
                {
                    numCount[k] += numCount[k - 1];
                }
    
                for (int k = 0; k < len; k++)
                {
                    int num = (arr[k] / curBit) % 10;
                    numCount[num] -= 1;
                    temp[numCount[num]] = arr[k];               
                }
    
                for (int j = 0; j < len; j++)
                {
                    arr[j] = temp[j];
                }
            }
        }
    
        int GetMaxBit(int[] arr, int len)
        {
            int max = arr[0];
    
            for (int i = 1; i < len; i++)
            {
                if (arr[i] > max)
                {
                    max = arr[i];
                }
            }
    
            int d = 0;
            while (max > 0)
            {
                d += 1;
                max /= 10;
            }
    
            return d;
        }
    }
  • 相关阅读:
    系统分析员、系统架构师、项目经理的区别
    C# 委托(Delegate) 事件(Event)应用详解
    项目管理的通俗解释
    什么是依赖注入
    程序员每天该做的事
    鸿蒙应用开发入门(三):开发第一个鸿蒙应用
    #2020征文手机# 零基础鸿蒙开发4 如何播放一个全屏视频(JS版)
    【资源下载】快来获取HarmonyOS官方通用规范图标
    #2020征文手机# 快速搭建一款鸿蒙分布式分歧终端机原型
    #2020征文TV#鸿蒙应用开发TVHelloWord (二) 传递数据、跳转
  • 原文地址:https://www.cnblogs.com/wang-jin-fu/p/11347546.html
Copyright © 2011-2022 走看看