zoukankan      html  css  js  c++  java
  • 基本排序算法

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

    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
  • 相关阅读:
    Codeforces 992C(数学)
    Codeforces 990C (思维)
    Codeforces 989C (构造)
    POJ 1511 Invitation Cards(链式前向星,dij,反向建边)
    Codeforces 1335E2 Three Blocks Palindrome (hard version)(暴力)
    POJ 3273 Monthly Expense(二分)
    POJ 2566 Bound Found(尺取前缀和)
    POJ 1321 棋盘问题(dfs)
    HDU 1506 Largest Rectangle in a Histogram(单调栈)
    POJ 2823 Sliding Window(单调队列)
  • 原文地址:https://www.cnblogs.com/tim-li/p/3327895.html
Copyright © 2011-2022 走看看