• C#实现十大排序算法


    using System;
    using System.Linq;
    using System.Collections.Generic;
    
    //by Alexander Ezharjan
    
    namespace Sort
    {
        class Program
        {
            static void Main(string[] args)
            {
                int[] myArray = new int[10] { 10, 6, 3, 4, 2, 7, 1, 5, 9, 8 };
                // BubbleSort(myArray);
                // SelectionSort(myArray);
                // InsertionSort(myArray);
                // ShellSort(myArray);
                // QuickSort(myArray);
                // HeapSort(myArray);
                // CountSort(myArray);
                foreach (int element in myArray)
                {
                    Console.Write("{0}  ", element);
                }
    
                List<int> myList = new List<int>(10) { 10, 6, 3, 4, 2, 7, 1, 5, 9, 8 };
                // List<int> newList = new List<int>(10) { 0 };
                // BucketSort(myList, 3, 6);
                // newList = RecursiveSort(myList);
                RadixSort(myList);
                Console.WriteLine("
    ");
                foreach (int element in myList)
                {
                    Console.Write("{0}  ", element);
                }
                // foreach (int element in newList)
                // {
                //     Console.Write("{0}  ", element);
                // }
            }
    
    
    
    
    
            static void Swap(ref int x, ref int y)
            {
                int temp = x;
                x = y;
                y = temp;
            }
    
    
    
    
            ///冒泡排序
            static void BubbleSort(int[] arr)
            {
                bool swapped;
                for (int i = 0; i < arr.Length; i++)
                {
                    swapped = false;
                    for (int j = 0; j < arr.Length - 1 - i; j++)
                        if (arr[j] > arr[j + 1])
                        {
                            Swap(ref arr[j], ref arr[j + 1]);
                            if (!swapped) swapped = true;
                        }
                    if (!swapped) return;
                }
            }
    
    
    
    
            ///选择排序
            static void SelectionSort(int[] arr)
            {
                int i, j, min, len = arr.Length;
                for (i = 0; i < len - 1; i++)
                {
                    min = i;
                    for (j = i + 1; j < len; j++)
                    {
                        if (arr[min].CompareTo(arr[j]) > 0)
                        {
                            min = j;
                        }
                    }
                    Swap(ref arr[min], ref arr[i]);
                }
            }
    
    
    
    
    
            ///插入排序
            static void InsertionSort(int[] arr)
            {
                for (int i = 1; i < arr.Length; i++)
                {
                    int temp = arr[i];
                    for (int j = i - 1; j >= 0; j--)
                    {
                        if (arr[j] > temp)
                        {
                            arr[j + 1] = arr[j];
                            arr[j] = temp;
                        }
                        else
                            break;
                    }
                }
            }
    
    
    
    
    
            ///希尔排序
            static void ShellSort(int[] arr)
            {
                int gap = 1;
    
                while (gap < arr.Length)
                {
                    gap = gap * 3 + 1;
                }
    
                while (gap > 0)
                {
                    for (int i = gap; i < arr.Length; i++)
                    {
                        int tmp = arr[i];
                        int j = i - gap;
                        while (j >= 0 && arr[j] > tmp)
                        {
                            arr[j + gap] = arr[j];
                            j -= gap;
                        }
                        arr[j + gap] = tmp;
                    }
                    gap /= 3;
                }
            }
    
    
    
            ///递归排序
            static List<int> RecursiveSort(List<int> list)
            {
                if (list.Count <= 1)
                {
                    return list;
                }
    
                int mid = list.Count / 2;
                List<int> left = new List<int>();  // 定义左侧List
                List<int> right = new List<int>(); // 定义右侧List
                                                   // 以下兩個循環把 lst 分為左右兩個 List
                for (int i = 0; i < mid; i++)
                {
                    left.Add(list[i]);
                }
                for (int j = mid; j < list.Count; j++)
                {
                    right.Add(list[j]);
                }
                left = RecursiveSort(left);
                right = RecursiveSort(right);
                return MergeSortedList(left, right);
            }
            /// <summary>
            /// 合併兩個已經排好序的List
            /// </summary>
            /// <param name="left">左側List</param>
            /// <param name="right">右側List</param>
            /// <returns></returns>
            static List<int> MergeSortedList(List<int> left, List<int> right)
            {
                List<int> temp = new List<int>();
                while (left.Count > 0 && right.Count > 0)
                {
                    if (left[0] <= right[0])
                    {
                        temp.Add(left[0]);
                        left.RemoveAt(0);
                    }
                    else
                    {
                        temp.Add(right[0]);
                        right.RemoveAt(0);
                    }
                }
                if (left.Count > 0)
                {
                    for (int i = 0; i < left.Count; i++)
                    {
                        temp.Add(left[i]);
                    }
                }
                if (right.Count > 0)
                {
                    for (int i = 0; i < right.Count; i++)
                    {
                        temp.Add(right[i]);
                    }
                }
                return temp;
            }
    
    
    
    
            ///快速排序(目标数组,数组的起始位置,数组的终止位置)
            static void QuickSort(int[] arr, int left = 0, int right = -1)
            {
    
                if (right.Equals(-1)) right = arr.Length - 1;
    
                try
                {
                    int keyValuePosition;   //记录关键值的下标
    
                    //当传递的目标数组含有两个以上的元素时,进行递归调用。(即:当传递的目标数组只含有一个元素时,此趟排序结束)
                    if (left < right)
                    {
                        keyValuePosition = Partion(arr, left, right);  //获取关键值的下标(快排的核心)
    
                        QuickSort(arr, left, keyValuePosition - 1);    //递归调用,快排划分出来的左区间
                        QuickSort(arr, keyValuePosition + 1, right);   //递归调用,快排划分出来的右区间
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception: {0}", ex);
                }
            }
    
            ///快速排序的核心部分:确定关键值在数组中的位置,以此将数组划分成左右两区间,关键值游离在外。(返回关键值应在数组中的下标)
            static int Partion(int[] arr, int left, int right)
            {
                int leftIndex = left;        //记录目标数组的起始位置(后续动态的左侧下标)
                int rightIndex = right;      //记录目标数组的结束位置(后续动态的右侧下标)
    
                int keyValue = arr[left];  //数组的第一个元素作为关键值
                int temp;
    
                //当 (左侧动态下标 == 右侧动态下标) 时跳出循环
                while (leftIndex < rightIndex)
                {
                    while (leftIndex < rightIndex && arr[leftIndex] <= keyValue)  //左侧动态下标逐渐增加,直至找到大于keyValue的下标
                    {
                        leftIndex++;
                    }
                    while (leftIndex < rightIndex && arr[rightIndex] > keyValue)  //右侧动态下标逐渐减小,直至找到小于或等于keyValue的下标
                    {
                        rightIndex--;
                    }
                    if (leftIndex < rightIndex)  //如果leftIndex < rightIndex,则交换左右动态下标所指定的值;当leftIndex==rightIndex时,跳出整个循环
                    {
                        temp = arr[leftIndex];
                        arr[leftIndex] = arr[rightIndex];
                        arr[rightIndex] = temp;
                    }
                }
    
                //当左右两个动态下标相等时(即:左右下标指向同一个位置),此时便可以确定keyValue的准确位置
                temp = keyValue;
                if (temp < arr[rightIndex])   //当keyValue < 左右下标同时指向的值,将keyValue与rightIndex - 1指向的值交换,并返回rightIndex - 1
                {
                    arr[left] = arr[rightIndex - 1];
                    arr[rightIndex - 1] = temp;
                    return rightIndex - 1;
                }
                else //当keyValue >= 左右下标同时指向的值,将keyValue与rightIndex指向的值交换,并返回rightIndex
                {
                    arr[left] = arr[rightIndex];
                    arr[rightIndex] = temp;
                    return rightIndex;
                }
            }
    
    
    
    
    
    
            /// <summary>
            /// 堆排序
            /// </summary>
            /// <param name="arr">待排序数组</param>
            static void HeapSort(int[] arr)
            {
                int nodeCount = arr.Length;
                int[] tempKey = new int[nodeCount + 1];
                // 元素索引从1开始
                for (int i = 0; i < nodeCount; i++)
                {
                    tempKey[i + 1] = arr[i];
                }
    
                // 初始数据建堆(从含最后一个结点的子树开始构建,依次向前,形成整个二叉堆)
                for (int i = nodeCount / 2; i >= 1; i--)
                {
                    Restore(tempKey, i, nodeCount);
                }
    
                // 不断输出堆顶元素、重构堆,进行排序
                for (int i = nodeCount; i > 1; i--)
                {
                    int temp = tempKey[i];
                    tempKey[i] = tempKey[1];
                    tempKey[1] = temp;
                    Restore(tempKey, 1, i - 1);
                }
    
                //排序结果
                for (int i = 0; i < nodeCount; i++)
                {
                    arr[i] = tempKey[i + 1];
                }
            }
    
            /// <summary>
            /// 二叉堆的重构(针对于已构建好的二叉堆首尾互换之后的重构)
            /// </summary>
            /// <param name="arr"></param>
            /// <param name="rootNode">根结点j</param>
            /// <param name="nodeCount">结点数</param>
            static void Restore(int[] arr, int rootNode, int nodeCount)
            {
                while (rootNode <= nodeCount / 2) // 保证根结点有子树
                {
                    //找出左右儿子的最大值
                    int m = (2 * rootNode + 1 <= nodeCount && arr[2 * rootNode + 1] > arr[2 * rootNode]) ? 2 * rootNode + 1 : 2 * rootNode;
    
                    if (arr[m] > arr[rootNode])
                    {
                        int temp = arr[m];
                        arr[m] = arr[rootNode];
                        arr[rootNode] = temp;
                        rootNode = m;
                    }
                    else
                    {
                        break;
                    }
                }
            }
    
    
            ///计数排序
            static void CountSort(int[] arr)
            {
                if (arr.Length == 0) return;
    
                int min = arr[0];
                int max = min;
    
                foreach (int number in arr)
                {
                    if (number > max)
                    {
                        max = number;
                    }
                    else if (number < min)
                    {
                        min = number;
                    }
                }
    
                int[] counting = new int[max - min + 1];
    
                for (int i = 0; i < arr.Length; i++)
                {
                    counting[arr[i] - min] += 1;
                }
    
                int index = -1;
                for (int i = 0; i < counting.Length; i++)
                {
                    for (int j = 0; j < counting[i]; j++)
                    {
                        index++;
                        arr[index] = i + min;
                    }
                }
            }
    
    
    
    
            ///桶排序
            static void BucketSort(List<int> list, int bucketCount, int maxBucketCount)
            {
                List<List<int>> buckets = new List<List<int>>(bucketCount);//二维列表
                for (int i = 0; i < bucketCount; i++)
                {
                    buckets.Add(new List<int>());
                }
                for (int i = 0; i < list.Count; i++)
                {
                    // int j = Mathf.Min(list[i] / (maxBucketCount / bucketCount), bucketCount - 1);//j表示改放的哪个桶,不能大于n-1
                    int j = Math.Min(list[i] / (maxBucketCount / bucketCount), bucketCount - 1);//j表示改放的哪个桶,不能大于n-1
                    buckets[j].Add(list[i]);//放入对应桶
                    for (int x = buckets[j].Count - 1; x > 0; x--)//放一个排序一次,两两对比就可以
                    {
                        if (buckets[j][x] < buckets[j][x - 1])//升序
                        {
                            int tmp = buckets[j][x];//交换
                            buckets[j][x] = buckets[j][x - 1];
                            buckets[j][x - 1] = tmp;
                        }
                        else
                        {
                            break;//如果不发生交换直接退出,因为前面的之前就排序好了
                        }
                    }
                }
                list.Clear();//输出
                for (int i = 0; i < buckets.Count; i++)
                {
                    list.AddRange(buckets[i]);
                }
            }
    
    
            ///基数排序
            static void RadixSort(List<int> list)
            {
                int maxValue = list.Max();//列表内部方法拿过来用用(在Linq中)
                int it = 0;//需要几趟
                           //maxvalue 9-1 99-2 999-3
                           //10^0<=9 10^1>9 it=1
                           //10^0<99 10^1<99 10^2>99 it=2
                while (Math.Pow(10, it) <= maxValue)
                {
                    List<List<int>> buckets = new List<List<int>>(10);//分10个桶对应0-9
                    for (int i = 0; i < 10; i++)
                    {
                        buckets.Add(new List<int>());
                    }//列表初始化大小
                    for (int i = 0; i < list.Count; i++)//入桶
                    {
                        //989 it=0 989/10^it=989 989%10=9;
                        int digit = (int)((list[i]) / (Math.Pow(10, it)) % 10);//得到对应桶
                        buckets[digit].Add(list[i]);
                    }//全部入桶
                    list.Clear();//依次取出来
                    for (int i = 0; i < buckets.Count; i++)
                    {
                        list.AddRange(buckets[i]);
                    }
                    it += 1;//继续下一次循环入桶出桶
                }
            }
        }
    }
    
    
    

    参考链接



    作者:艾孜尔江

  • 相关阅读:
    PAT甲级1137Final Grading
    晚测6
    模拟15
    模拟14
    模拟13
    晚测5
    晚测4
    模拟11
    7012. 2021.03.15【2021省赛模拟】十
    7011. 2021.03.13【2021省赛模拟】nonintersect
  • 原文地址:https://www.cnblogs.com/ezhar/p/13783108.html
Copyright © 2020-2023  润新知