首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >常用排序算法

常用排序算法
EN

Code Review用户
提问于 2017-09-22 21:13:00
回答 2查看 556关注 0票数 1

在这里,我已经为下面的算法准备了我的解决方案,并且好奇是否有一种方法来优化它们。欢迎并感谢您的任何意见!

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;

namespace algotest
{
    class Program
    {
        static void InsertionSort(int[] arr)
        {
            for (int i = 1; i < arr.Length; ++i)
            {
                int temp = arr[i];
                bool sorted = false;

                for (int j = i - 1; j >= 0 && !sorted;)
                {
                    if (temp < arr[j])
                    {
                        arr[j + 1] = arr[j];
                        --j;
                        arr[j + 1] = temp;
                    }
                    else
                    {
                        sorted = true;
                    }
                }
            }
        }

        static void BubbleSort(int[] arr)
        {
            int temp = 0;

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

        static void SelectionSort(int[] arr)
        {
            int temp, min;

            for (int i = 0; i < arr.Length - 1; ++i)
            {
                min = i;

                for (int j = i + 1; j < arr.Length; ++j)
                {
                    if (arr[j] < arr[min])
                    {
                        min = j;
                    }
                }

                temp = arr[min];
                arr[min] = arr[i];
                arr[i] = temp;
            }
        }

        static void Merge(int[] arr, int left, int pivot, int right)
        {
            int[] temp = new int[25];
            int index = left;
            int leftBound = pivot - 1;
            int length = right - left + 1;

            while (left <= leftBound && pivot <= right)
            {
                if (arr[left] <= arr[pivot])
                {
                    temp[index++] = arr[left++];
                }
                else
                {
                    temp[index++] = arr[pivot++];
                }
            }

            while (left <= leftBound)
            {
                temp[index++] = arr[left++];
            }

            while (pivot <= right)
            {
                temp[index++] = arr[pivot++];
            }

            for (int i = 0; i < length; i++)
            {
                arr[right] = temp[right];
                right--;
            }
        }

        static void MergeSort(int[] arr, int left, int right)
        {
            if (right > left)
            {
                int pivot = (right + left) / 2;
                MergeSort(arr, left, pivot);
                MergeSort(arr, pivot + 1, right);
                Merge(arr, left, pivot + 1, right);
            }
        }

        static void QuickSort(int[] arr, int left, int right)
        {
            int i = left, j = right;
            int pivot = arr[(left + right) / 2];

            while (i <= j)
            {
                while (arr[i].CompareTo(pivot) < 0)
                {
                    ++i;
                }

                while (arr[j].CompareTo(pivot) > 0)
                {
                    --j;
                }

                if (i <= j)
                {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;

                    ++i;
                    --j;
                }
            }

            if (left < j)
            {
                QuickSort(arr, left, j);
            }

            if (i < right)
            {
                QuickSort(arr, i, right);
            }
        }

        static void Heapify(int[] arr, int i, int n)
        {
            try
            {
                int temp = arr[i];
                int j = 2 * i;

                while (j <= n)
                {
                    if (j < n && arr[j] < arr[j + 1])
                    {
                        j++;
                    }

                    if (temp >= arr[j])
                    {
                        break;
                    }

                    arr[j / 2] = arr[j];
                    j *= 2;
                }

                arr[j / 2] = temp;
            }
            catch (IndexOutOfRangeException err)
            {
                Console.WriteLine("Array Out of Bounds ", err);
            }
        }

        static void HeapSort(int[] arr)
        {
            for (int i = arr.Length / 2; i >= 0; --i)
            {
                Heapify(arr, i, arr.Length - 1);
            }

            for (int i = arr.Length - 2; i >= 0; --i)
            {
                int temp = arr[i + 1];
                arr[i + 1] = arr[0];
                arr[0] = temp;

                Heapify(arr, 0, i);
            }
        }

        static void CountingSort(int[] arr)
        {
            int[] count = new int[arr.Max() + 1];

            for (int i = 0; i < arr.Length; ++i)
            {
                ++count[arr[i]];
            }

            int j = 0;

            for (int i = 0; i < count.Length; ++i)
            {
                for (int k = 0; k < count[i]; ++k)
                {
                    arr[j++] = i;
                }
            }
        }

        static void RadixSort(int[] arr)
        {
            int i, j;
            int[] temp = new int[arr.Length];

            for (int shift = 31; shift > -1; --shift)
            {
                j = 0;

                for (i = 0; i < arr.Length; ++i)
                {
                    bool move = (arr[i] << shift) >= 0;

                    if (shift == 0 ? !move : move)
                    {
                        arr[i - j] = arr[i];
                    }
                    else
                    {
                        temp[j++] = arr[i];
                    }
                }

                Array.Copy(temp, 0, arr, arr.Length - j, j);
            }
        }

        static void BucketSort(int[] arr)
        {
            // bucket size key:
            // array 1-99 ; 10 buckets
            // arrat 100-199 ; 20 buckets
            // etc.
            // TODO: Implement logic to determine bucket size?

            int numOfBuckets = 10;
            List<int> result = new List<int>();
            List<int>[] buckets = new List<int>[numOfBuckets];

            for (int i = 0; i < numOfBuckets; ++i)
            {
                buckets[i] = new List<int>();
            }

            for (int i = 0; i < arr.Length; ++i)
            {
                int index = arr[i] / numOfBuckets;
                buckets[index].Add(arr[i]);
            }

            for (int i = 0; i < numOfBuckets; ++i)
            {
                int[] temp = buckets[i].ToArray();
                InsertionSort(arr);
                result.AddRange(temp);
            }

            arr = result.ToArray();
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Please select an algorithm: ");
            Console.WriteLine("I : InsertionSort O(n^2)");
            Console.WriteLine("B : BubbleSort O(n^2)");
            Console.WriteLine("S : SelectionSort O(n^2)");
            Console.WriteLine("M : MergeSort O(nlgn)");
            Console.WriteLine("Q : QuickSort O(nlgn)");
            Console.WriteLine("H : HeapSort O(nlgn)");
            Console.WriteLine("C : CountingSort O(n)");
            Console.WriteLine("R : RadixSort O(n)");
            Console.WriteLine("U : BucketSort O(n)");

            string algorithm = Console.ReadLine().ToUpper();

            Console.WriteLine("How many elements?");

            int numOfElements = int.Parse(Console.ReadLine());
            int[] arr = new int[numOfElements];
            Random rand = new Random();

            Console.WriteLine("Generating random data...");

            for (int i = 0; i < numOfElements; ++i)
            {
                arr[i] = rand.Next(100);
            }

            switch (algorithm)
            {
                case "I":
                    InsertionSort(arr);
                    break;
                case "B":
                    BubbleSort(arr);
                    break;
                case "S":
                    SelectionSort(arr);
                    break;
                case "M":
                    MergeSort(arr, 0, arr.Length - 1);
                    break;
                case "Q":
                    QuickSort(arr, 0, arr.Length - 1);
                    break;
                case "H":
                    HeapSort(arr);
                    break;
                case "C":
                    CountingSort(arr);
                    break;
                case "R":
                    RadixSort(arr);
                    break;
                case "U":
                    BucketSort(arr);
                    break;
            }

            for (int i = 0; i < arr.Length; ++i)
            {
                Console.WriteLine(arr[i]);
            }

            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
}
EN

回答 2

Code Review用户

回答已采纳

发布于 2017-09-22 21:50:31

插入排序

您不需要标志变量sorted。而不是sorted = true,您可以简单地将break从循环中剔除。

可以避免多次标记变量,从而产生更简单、更易读的解决方案。始终以可疑的方式查看标志变量。

合并排序

int[] temp = new int[25]中的数字25看起来是任意的。为什么是25?

请注意,这可能导致整数溢出,这是合并排序实现中的一个常见缺陷:

int枢轴=(右+左)/ 2;

修复方法非常简单:

代码语言:javascript
复制
int pivot = left + (right - left) / 2;

计数排序

实现分配一个大小为arr.Max() + 1的数组作为存储。最好也考虑到arr.Min(),以避免分配超出必要的空间。

此外,如果输入包含负数,当前的实现将崩溃。这也是考虑arr.Min()的另一个原因。

票数 3
EN

Code Review用户

发布于 2017-09-23 06:11:53

插入排序

您似乎在反复编写不需要的移动元素,而且正如前面提到的,有一个不需要的sorted标志,因此您可以从循环中跳出,放置移动元素。

代码语言:javascript
复制
    static void InsertionSort(int[] arr)
    {
        for (int i = 1; i < arr.Length; ++i)
        {
            int temp = arr[i];
            int j = i - 1;

            while (j >= 0)
            {
                if (temp >= arr[j])   break; // found insertion point

                arr[j + 1] = arr[j];
                --j;
            }
            arr[j + 1] = temp;
        }
    }

气泡排序

通常,气泡排序指的是交换相邻元素。可以通过跟踪上一个交换来优化它。

代码语言:javascript
复制
    static void BubbleSort(int[] arr)
    {
        int endPt = arr.Length - 1;
        while (endPt > 0)
        {
            int lastSwap = 0;
            for (int j = 0; j < endPt; ++j)
            {
                if (arr[j] > arr[j+1])
                {
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                    lastSwap = j;
                }
            }
            endPt = lastSwap;
        }
    }

选择排序

没有任何问题,尽管您的变量声明距离它们的使用点比前面的例程稍微远一点。

..。我以后可能会再看看。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/176340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档