基本排序算法

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

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

 

 

你可能感兴趣的:(排序算法)