天天看點

一些排序算法

冒泡排序

private void BubbleSort(int[] array)
    {
        bool isSwapped;
        for (int i = 0; i < array.Length; i++)
        {
            isSwapped = false;
            //經過這一趟 最大的數已經到底
            for (int j = 0; j < array.Length - 1 - i; j++)
            {
                int v1 = array[j];
                int v2 = array[j + 1];
                if (v1 > v2)
                {
                    array[j] = v2;
                    array[j + 1] = v1;

                    isSwapped = true;
                }
            }

            //沒有發生過交換說明已經有序
            if (!isSwapped)
                break;
        }
    }
           

選擇排序

private void SelectionSort(int[] array)
    {
        for (int i = 0; i < array.Length - 1; i++)
        {
            int minIndex = i;

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

            int temp = array[minIndex];
            array[minIndex] = array[i];
            array[i] = temp;
        }
    }
           

插入排序

private void InsertSort(int[] array)
    {
        for (int i = 1; i < array.Length; i++)
        {
            int temp = array[i];
            for (int j = i - 1; j >= 0; j--)
            {
                int val = array[j];
                if (val > temp)
                {
                    array[j + 1] = val;
                    array[j] = temp;
                }
                else
                    break;
            }
        }
    }
           

希爾排序

private void ShellSort(int[] array, int gap)
    {
        while (true)
        {
            //以步長為gap做直接插入排序
            for (int k = 0; k < gap; k++)
            {
                //以gap為步長的每一次直接插入排序
                for (int i = gap + k; i < array.Length; i += gap)
                {
                    int temp = array[i];

                    for (int j = i - gap; j >= 0; j -= gap)
                    {
                        int val = array[j];
                        if (val > temp)
                        {
                            array[j] = temp;
                            array[j + gap] = val;
                        }
                        else
                            break;
                    }
                }

            }

            //做完步長為1後退出
            if (gap == 1)
                break;

            //每次減少步長
            gap = gap / 2 == 0 ? 1 : gap / 2;
        }
    }
           

歸并排序

private List<int> Sort(List<int> array)
    {
        if (array.Count <= 1)
            return array;

        int mid = array.Count / 2;

        List<int> left = new List<int>();
        List<int> right = new List<int>();
        for (int i = 0; i < mid; i++)
            left.Add(array[i]);
        for (int i = mid; i < array.Count; i++)
            right.Add(array[i]);

        left = Sort(left);
        right = Sort(right);

        return Merge(left, right);
    }

    private List<int> Merge(List<int> left, List<int> right)
    {
        List<int> result = new List<int>();

        int i = 0, j = 0;
        int v1 = 0, v2 = 0;
        while (i < left.Count && j < right.Count)
        {
            v1 = left[i];
            v2 = right[j];

            if (v1 <= v2)
            {
                result.Add(v1);
                i++;
            }
            else
            {
                result.Add(v2);
                j++;
            }
        }

        //将剩餘的數直接挪到result中
        if (j >= right.Count)
        {
            for (int k = i; k < left.Count; k++)
            {
                result.Add(left[k]);
            }
        }
        if (i >= left.Count)
        {
            for (int k = j; k < right.Count; k++)
            {
                result.Add(right[k]);
            }
        }

        return result;
    }

	//更簡單的寫法
    private List<int> Merge(List<int> left, List<int> right)
    {
        List<int> result = new List<int>();

        int v1 = 0, v2 = 0;
        while (left.Count > 0 && right.Count > 0)
        {
            v1 = left[0];
            v2 = right[0];

            if (v1 <= v2)
            {
                result.Add(v1);
                left.RemoveAt(0);
            }
            else
            {
                result.Add(v2);
                right.RemoveAt(0);
            }
        }

        //将剩餘的數直接挪到result中
        if (left.Count > 0)
        {
            for (int k = 0; k < left.Count; k++)
            {
                result.Add(left[k]);
            }
        }
        if (right.Count > 0)
        {
            for (int k = 0; k < right.Count; k++)
            {
                result.Add(right[k]);
            }
        }

        return result;
    }
           

快速排序

private void QuickSort(List<int> array, int left, int right)
    {
        if (left < right)
        {
            int mid = Sort(array, left, right);
            QuickSort(array, left, mid - 1);
            QuickSort(array, mid + 1, right);
        }
    }

    private int Sort(List<int> array, int left, int right)
    {
        int temp = array[left];
        while (left < right)
        {
            while (left < right && temp <= array[right])
            {
                right--;
            }
            array[left] = array[right];

            while (left < right && temp >= array[left])
            {
                left++;
            }

            array[right] = array[left];
        }

        array[right] = temp;

        return right;
    }

	//非遞歸版
	//利用棧,其實遞歸本質上也是利用棧
    private void QuickSort(List<int> array, int left, int right)
    {
        Stack<int> stack = new Stack<int>();
        stack.Push(left);
        stack.Push(right);

        while (stack.Count > 0)
        {
            right = stack.Pop();
            left = stack.Pop();

            int mid = Sort(array, left, right);

            if (left < mid - 1)
            {
                stack.Push(left);
                stack.Push(mid - 1);
            }
            if (mid + 1 < right)
            {
                stack.Push(mid + 1);
                stack.Push(right);
            }
        }
    }
           

繼續閱讀