• 基本排序算法


          没有过多的说明,只为将来可能会用到的日子,能拿来做参考。

    1、冒泡(Bubble)

            7 5 2 1 5 9
            5 7 2 1 5 9
            5 2 7 1 5 9
            5 2 1 7 5 9
            5 2 1 5 7 9

            2 5 1 5 7 9
            2 1 5 5 7 9
            2 1 5 5 7 9

            1 2 5 5 7 9

            public static void BubbleSort(int[] a)
            {
                int n = a.Length - 1;//个数
                int i, j;//用于控制循环
                int tmp;//中间变量
                bool isChange;//记录冒泡一轮下来是否发生交换(如果没有发生交换证明已排好序)
                for (i = 0; i < n; i++)
                {
                    isChange = false;
                    for (j = 0; j < n - i; j++)//每轮冒泡过后要对比的数就少一个
                    {
                        if (a[j] > a[j + 1])//大的数向上冒
                        {
                            tmp = a[j];
                            a[j] = a[j + 1];
                            a[j + 1] = tmp;
                            isChange = true;
                        }
                    }
                    if (!isChange)
                    {
                        return;
                    }
    
                }
                return;
            }
    View Code

    2、直接插入(Insert)

            7 5 2 1 5 9
            5 7 2 1 5 9
            2 5 7 1 5 9
            1 2 5 7 5 9
            1 2 5 5 7 9

            public static void InsertSort(int[] a)
            {
                int n = a.Length;
                for (int i = 1; i < n; i++)//循环从第二个数组元素开始,因为arr[0]作为最初已排序部分
                {
                    int temp = a[i];//temp标记为未排序第一个元素
                    int j = i - 1;
                    while (j >= 0 && a[j] > temp)//将temp与已排序元素从小到大比较,寻找temp应插入的位置
                    {
                        a[j + 1] = a[j];
                        j--;
                    }
                    a[j + 1] = temp;
                }
            }
    View Code

    3、直接选择(Select)

            7 5 2 1 5 9
            1 5 2 7 5 9
            1 2 5 7 5 9
            1 2 5 7 5 9
            1 2 5 5 7 9

            public static void SelectSort(int[] a)
            {
                int n = a.Length;//个数
                int i, j;
                int tmp;
                int b;
                for (i = 0; i < n - 1; i++)
                {
                    tmp = i;
                    for (j = i + 1; j < n; j++)
                    {
                        if (a[tmp] > a[j])//每轮找到最小的元素
                            tmp = j;
                    }
                    if (i != tmp)
                    {
                        b = a[tmp];
                        a[tmp] = a[i];
                        a[i] = b;
                    }
                }
            }
    View Code

    4、快速(Quick)

            7       5 2 1 5 9
            5   2 1 5     7 9
            2 1 5   5     7 9
            1 2 5   5     7 9

            public static void QuickSort(int[] a, int low, int high)
            {
                if (low < high)
                {                                     // ↓                     ↓
                    int point = MovePart(a, low, high);// 5 6 2 1 4 9      4 1 2 5 6 9
                    QuickSort(a, low, point);
                    QuickSort(a, point + 1, high);
                }
            }
    
            public static int MovePart(int[] a, int partLow, int partHigh)
            {
                int pivotP = partLow;//记住枢纽位置
                while (partLow < partHigh)
                {
                    while (partLow < partHigh && a[partHigh] >= a[pivotP])//右往左找第一个小于pivot的数
                    {
                        partHigh--;
                    }
                    Swap(a, pivotP, partHigh);
                    pivotP = partHigh;
                    while (partLow < partHigh && a[partLow] <= a[pivotP])//左往右找第一个大于prvot的数
                    {
                        partLow++;
                    }
                    Swap(a, partLow, pivotP);
                    pivotP = partLow;
                }
                return pivotP;//返回分割点
            }
    
            public static void Swap(int[] a, int pivotP, int swapP)
            {
                int t;
                t = a[pivotP];
                a[pivotP] = a[swapP];
                a[swapP] = t;
            }
    View Code

    5、希尔(Shell)

            7 5 2 1 5 9
            7 5 2   1 5 9
            7 5   2   1 5  9
            5 7   2   1 5  9
            2 5   7   1 5  9
            2 5 7   1 5 9
            1 2 5 7 5 9
            1 2 5 5 7 9

            public static void ShellSort(int[] a)
            {
                int n = a.Length;
                for (int incr = 3; incr > 0; incr--)//增量递减,增量据说以9 5 3 1最优(各种大牛到现在都没有定论),此处为3 2 1
                {
                    for (int L = 0; L < (n - 1) / incr; L++)//重复分成的每个子列表
                    {
                        for (int i = L + incr; i < n; i += incr)//对每个子列表应用插入排序
                        {
                            int temp = a[i];
                            int j = i - incr;
                            while (j >= 0 && a[j] > temp)
                            {
                                a[j + incr] = a[j];
                                j -= incr;
                            }
                            a[j + incr] = temp;
                        }
                    }
                }
            }
    View Code

    6、归并(Merge)

            7 5 2 1 5 9
            7 5 2    1 5 9
            7   5 2   1   5 9
            7   2 5   1   5 9
            2 5 7    1 5 9
            1 2 5 5 7 9

            public static void Merge(int[] a, int low, int center, int high)
            {
                if (low >= high) return;
                int m = center - low + 1;
                int n = high - center;
                int[] L = new int[m];
                int[] R = new int[n];
                int i, j, k;
                for (i = 0; i < m; ++i) L[i] = a[low + i];//取得左边数
                for (i = 0; i < n; ++i) R[i] = a[low + i + m];//取得右边数
    
                for (i = 0, j = 0, k = low; i < m && j < n; ++k)
                {
                    if (L[i] > R[j])//从L、R两边选比较小的数放进a,直到一边放完
                    {
                        a[k] = R[j];
                        j++;
                    }
                    else
                    {
                        a[k] = L[i];
                        i++;
                    }
                }
                while (i < m)//如果是L没放完,把L剩余的数放进a
                {
                    a[k] = L[i];
                    k++;
                    i++;
                }
                while (j < n)//如果是R没放完,把R剩余的数放进a
                {
                    a[k] = R[j];
                    k++;
                    j++;
                }
            }
    
            public static void MergeSort(int[] a, int low, int high)
            {
                int center;
                if (low < high)
                {
                    center = (low + high) / 2;
                    MergeSort(a, low, center);
                    MergeSort(a, center + 1, high);
                    Merge(a, low, center, high);
                }
            }
    View Code

    7、堆(Heap)

            7 5 2 1 5 9
                7
               /
              5   2
             / /
             1 5 9

                9
               /
              5   7
             / /
             1 5 2

            /// <summary>
            /// 堆排序,此处为倒序,要升序,请使用大二叉堆,或对数组进行首尾交换
            /// </summary>
            /// <param name="a"></param>
            /// <param name="n"></param>
            public static void HeapSort(int[] a, int n)
            {
                MakeMinHeap(a, n);//将数组建立成最小堆
                for (int i = n - 1; i >= 1; i--)
                {
                    Swap(a, i, 0);//把该论得到的最小数排到末尾已拍好序的的数前
                    MinHeapFixDown(a, 0, i);//排除末尾拍好序的的数得出子二叉堆,在作调整得出新的二叉堆,root又为最小的数
                }
    
            }
    
            /// <summary>
            /// 新加入叶子结点 
            /// </summary>
            /// <param name="a"></param>
            /// <param name="leafPoint">叶子结点所在位置</param>
            public static void MinHeapAddPoint(int[] a, int leafPoint)//以叶子结点,叶子结点的父结点,叶子结点的爷结点...为一组进行直接插入
            {
                int fartherPoint, temp,currentPornt;
                temp = a[leafPoint];
                currentPornt = leafPoint;//记录当前节点位置
                fartherPoint = (leafPoint - 1) / 2;      //父结点  
                while (a[fartherPoint] > a[currentPornt]&& currentPornt!=0)
                {
                    a[currentPornt] = a[fartherPoint];
                    currentPornt = fartherPoint;
                    fartherPoint = (currentPornt - 1) / 2;//父结点为的位置为 (currentPoint - 1) / 2
                }
                a[currentPornt] = temp;
            }
    
            /// <summary>
            /// 在最小堆中加入新的数据num  (从叶子结点(数组尾)插入)
            /// </summary>
            /// <param name="a"></param>
            /// <param name="n">新增结点位置(数组结尾位置+1 即 数组长度)</param>
            /// <param name="num">新增结点值</param>
            public static void MinHeapAddNumber(int[] a, int n, int num)
            {
                a[n] = num;
                MinHeapAddPoint(a, n);
            }
    
            /// <summary>
            /// 删除跟结点(将最后的结点a[n]放到根节点a[0]的位置)后的堆调整
            /// 从i整节点向下开始调整,n为节点总数, 从0开始计算 i节点的子节点为 2*i+1, 2*i+2  
            /// </summary>
            /// <param name="a">数组</param>
            /// <param name="fatherPoint">要调整的位置</param>
            /// <param name="n">二叉堆的长度(要调整到数组的那个位置)</param>
            public static void MinHeapFixDown(int[] a, int fatherPoint, int n)
            {
                int sonPoint, temp;
                temp = a[fatherPoint];
                sonPoint = 2 * fatherPoint + 1;//左子结点,右子节点为sonPoint+1 子节点为 2*i+1, 2*i+2
                while (sonPoint <n)
                {
                    if (sonPoint + 1 < n && a[sonPoint + 1] < a[sonPoint]) //存在右子结点的话,在左右孩子中找较小数  
                        sonPoint++;
    
                    if (a[sonPoint] >= temp)//再和父结点对比,如果父结点比较大不用做交换
                        break;
                    else
                    {//否则把较小的子结点往上移动,替换它的父结点  
                        a[fatherPoint] = a[sonPoint];     
                        fatherPoint = sonPoint;
                        sonPoint = 2 * fatherPoint + 1;
                    }
                }
                a[fatherPoint] = temp;
            }
    
            /// <summary>
            /// 在最小堆中删除数(删除根节点)
            /// </summary>
            /// <param name="a"></param>
            /// <param name="n">结点个数</param>
            public static void MinHeapDeleteNumber(int[] a, int n)
            {
                Swap(a, 0, n - 1); //互换根节点和叶子结点后
                MinHeapFixDown(a, 0, n - 1);//向下调整
            }
       
            /// <summary>
            /// 建立最小堆 n为结点总数
            /// </summary>
            /// <param name="a">数组</param>
            /// <param name="n">结点总数</param>
            public static void MakeMinHeap(int[] a, int n)
            {
                for (int i = (n-1-1)/ 2 ; i >= 0; i--)//由最后一个结点的父结点开始向下调整
                    MinHeapFixDown(a, i, n);
            }
    View Code
  • 相关阅读:
    HDU 1847
    HDU 1717
    KMP未优化模板、
    Codeforces Round #340 (Div. 2) B. Chocolate
    HDU 1042 N!
    HDU 1018 Big Number
    HDU 1031 Design T-Shirt
    解决Windows 7删除执行过的 EXE、Bat文件有延迟的问题
    修改Android手机的“虚拟机堆大小”和android:largeHeap来防止APP内存溢出问题
    Android引用百度定位API第三方组件后导致其它.so文件无法正常加载的问题
  • 原文地址:https://www.cnblogs.com/tim-li/p/3327895.html
Copyright © 2020-2023  润新知