C#排序

 public static class SortingHelper<T> where T : IComparable
    {
        #region 1.1 直接插入排序
        /// <summary>
        /// 普通版直接插入排序
        /// </summary>
        /// <param name="arr">待排序数组</param>
        public static void StraightInsertSort(T[] arr)
        {
            int i, j;
            T temp;
            for (i = 1; i < arr.Length; i++)
            {
                j = i - 1;
                temp = arr[i];
                while (j >= 0 && temp.CompareTo(arr[j]) < 0)
                {
                    arr[j + 1] = arr[j];
                    j--;
                }
                arr[j + 1] = temp;
            }
        }

        /// <summary>
        /// 加入哨兵版直接插入排序
        /// </summary>
        /// <param name="arr">待排序数组</param>
        public static void StraightInsertSortWithSentry(T[] arr)
        {
            int i, j;
            for (i = 1; i < arr.Length; i++)
            {
                j = i - 1;
                arr[0] = arr[i]; // 将插入元素存放于监哨arr[0]中
                while (arr[0].CompareTo(arr[j]) < 0)
                {
                    arr[j + 1] = arr[j]; // 移动记录
                    j--;
                }
                arr[j + 1] = arr[0]; // 将插入元素插入到合适的位置
            }
        }
        #endregion

        #region 1.2 希尔排序
        public static void ShellSort(T[] arr)
        {
            int i, j, d;
            T temp;
            for (d = arr.Length / 2; d >= 1; d = d / 2)
            {
                for (i = d; i < arr.Length; i++)
                {
                    j = i - d;
                    temp = arr[i];

                    while (j >= 0 && temp.CompareTo(arr[j]) < 0)
                    {
                        arr[j + d] = arr[j];
                        j = j - d;
                    }

                    arr[j + d] = temp;
                }
            }
        }
        #endregion

        #region 1.3 冒泡排序
        public static void BubbleSort(T[] arr)
        {
            int i, j;
            T temp;
            bool isExchanged = true;
            for (j = 1; j < arr.Length && isExchanged; j++)
            {
                isExchanged = false;
                for (i = 0; i < arr.Length - j; i++)
                {
                    if (arr[i].CompareTo(arr[i + 1]) > 0)
                    {
                        // 核心操作:交换两个元素
                        temp = arr[i];
                        arr[i] = arr[i + 1];
                        arr[i + 1] = temp;
                        // 附加操作:改变标志
                        isExchanged = true;
                    }
                }
            }
        }

        public static void BubbleSort(T[] arr, Comparison<T> comp)
        {
            int i, j;
            T temp;
            bool isExchanged = true;

            for (j = 1; j < arr.Length && isExchanged; j++)
            {
                isExchanged = false;
                for (i = 0; i < arr.Length - j; i++)
                {
                    if (comp(arr[i], arr[i + 1]) > 0)
                    {
                        // 核心操作:交换两个元素
                        temp = arr[i];
                        arr[i] = arr[i + 1];
                        arr[i + 1] = temp;
                        // 附加操作:改变标志
                        isExchanged = true;
                    }
                }
            }
        }
        #endregion


        #region 1.4 快速排序
        public static void QuickSort(T[] arr, int low, int high)
        {
            if (low < high)
            {
                int index = Partition(arr, low, high);

                // 对左区间递归排序
                QuickSort(arr, low, index - 1);

                // 对右区间递归排序
                QuickSort(arr, index + 1, high);
            }
        }

        private static int Partition(T[] arr, int low, int high)
        {
            int i = low, j = high;
            T temp = arr[i]; // 确定第一个元素作为"基准值"
            while (i < j)
            {
                // Stage1:从右向左扫描直到找到比基准值小的元素
                while (i < j && arr[j].CompareTo(temp) >= 0)
                {
                    j--;
                }
                // 将比基准值小的元素移动到基准值的左端
                arr[i] = arr[j];

                // Stage2:从左向右扫描直到找到比基准值大的元素
                while (i < j && arr[i].CompareTo(temp) <= 0)
                {
                    i++;
                }
                // 将比基准值大的元素移动到基准值的右端
                arr[j] = arr[i];
            }

            // 记录归位
            arr[i] = temp;

            return i;
        }

        #endregion

        #region 1.5 简单选择排序
        public static void SimpleSelectSort(T[] arr)
        {
            int i, j, k;
            T temp;

            for (i = 0; i < arr.Length - 1; i++)
            {
                k = i; // k用于记录每一趟排序中最小元素的索引号
                for (j = i + 1; j < arr.Length; j++)
                {
                    if (arr[j].CompareTo(arr[k]) < 0)
                    {
                        k = j;
                    }
                }

                if (k != i)
                {
                    // 交换arr[k]和arr[i]
                    temp = arr[k];
                    arr[k] = arr[i];
                    arr[i] = temp;
                }
            }
        }
        #endregion

        #region 1.6 堆排序
        public static void HeapSort(T[] arr)
        {
            int n = arr.Length; // 获取序列的长度
            // 构造初始堆
            for (int i = n / 2 - 1; i >= 0; i--)
            {
                Sift(arr, i, n - 1);
            }
            // 进行堆排序
            T temp;
            for (int i = n - 1; i >= 1; i--)
            {
                temp = arr[0];       // 获取堆顶元素
                arr[0] = arr[i];     // 将堆中最后一个元素移动到堆顶
                arr[i] = temp;       // 最大元素归位,下一次不会再参与计算

                Sift(arr, 0, i - 1); // 重新递归调整堆
            }
        }

        private static void Sift(T[] arr, int low, int high)
        {
            // i为欲调整子树的根节点索引号,j为这个节点的左孩子
            int i = low, j = 2 * i + 1;
            // temp记录根节点的值
            T temp = arr[i];

            while (j <= high)
            {
                // 如果左孩子小于右孩子,则将要交换的孩子节点指向右孩子
                if (j < high && arr[j].CompareTo(arr[j + 1]) < 0)
                {
                    j++;
                }
                // 如果根节点小于它的孩子节点
                if (temp.CompareTo(arr[j]) < 0)
                {
                    arr[i] = arr[j]; // 交换根节点与其孩子节点
                    i = j;  // 以交换后的孩子节点作为根节点继续调整其子树
                    j = 2 * i + 1;  // j指向交换后的孩子节点的左孩子
                }
                else
                {
                    // 调整完毕,可以直接退出
                    break;
                }
            }
            // 使最初被调整的节点存入正确的位置
            arr[i] = temp;
        }
        #endregion

        #region 1.7 二路归并排序
        public static void MergeSort(T[] arr, int low, int high)
        {
            if (low < high)
            {
                int mid = (low + high) / 2;
                MergeSort(arr, low, mid);       // 归并左边的子序列(递归)
                MergeSort(arr, mid + 1, high);  // 归并右边的子序列(递归)
                Merge(arr, low, mid, high);     // 归并当前前序列
            }
        }

        private static void Merge(T[] arr, int low, int mid, int high)
        {
            // result为临时空间,用于存放合并后的序列
            T[] result = new T[high - low + 1];
            int i = low, j = mid + 1, k = 0;
            // 合并两个子序列
            while (i <= mid && j <= high)
            {
                if (arr[i].CompareTo(arr[j]) < 0)
                {
                    result[k++] = arr[i++];
                }
                else
                {
                    result[k++] = arr[j++];
                }
            }
            // 将左边子序列的剩余部分复制到合并后的序列
            while (i <= mid)
            {
                result[k++] = arr[i++];
            }
            // 将右边子序列的剩余部分复制到合并后的序列
            while (j <= high)
            {
                result[k++] = arr[j++];
            }
            // 将合并后的序列覆盖合并前的序列
            for (k = 0, i = low; i <= high; k++, i++)
            {
                arr[i] = result[k];
            }
        }
        #endregion

    }

  

posted @ 2020-05-30 13:31  石shi  阅读(226)  评论(0编辑  收藏  举报