基本排序算法

前言:

该算法总结针对的是算法设计与分析课程所提到的算法,对于不同的人群可能获益有所不同,在叙述时会对一些较为简单的算法进行概性描述,目的是简单的告诉读者算法实现的基本原理,对一些较为复杂的算法则会付诸大量的笔墨,以求对算法的理解能够更加的透彻,这篇总结本人也会在博客上发布,以便长久性存储和便捷性阅读,其中描述错误或者不当的地方也请各位看官不吝赐教,菜鸡一个,谅解谅解。

排序种类:插入排序,选择排序,交换排序,归并排序

1.插入排序(Insertion-sort)

输入条件:待排序的数字预先存储在一个一维数组A[]中,共n个数

自然语言描述:从第二个数字元素开始直到最后一个数字结束,循环中的每一步将当前元素插进前面已经有序的数字序列当中,最终得到排序的数组

伪代码:

         For i=2:n

             Key=A[i];

             Insert(key)//将key插入小标i前的已排序数列的合适位置

      对于插入的方法有可以有不同的插入排序分类

            折半插入:折半寻找元素插入点,插入后将后面的元素向后移动一位

            直接插入:一边查找一边移动,直至找到插入点就停止

                For(i=2:n)//直接插入

                   Key=A[i];

                     j=i-1;

                     while j>0&&A[j]>key

                            A[j+1]=A[j];//如果比key大就往前移动

                            j=j-1;//j指针向后移动

                            A[j+1]=key;//找到位置后key赋值给当前的数组元素,

                                        这时A[j]>key为假。While循环结束

 算法复杂度:O^2

联想:C++有专门进行数组排序的函数:sort  头文件<algorithm>

        函数思想:快速排序

        排序对象:list,vector,或者int型数组

        用法:sort(begin,end,compare);

         Sort(A,A+n);//compare缺省时默认升序排列从下标0开始的n个数组元素

         Sort(A,A+n,compare)//按照compare中规定次序排列

         Bool compare(int i,int j){returni<j;}//升序排列

         Boolcompare(int I,int j){return i>j;}//降序排列

     发现: string str(“abcs”);

            String s(str.rbegin(),str.rend());//这时的s为str的逆序即”scba”

2.选择排序(Selection-sort)

    输入条件:A[n]—n个元素的数组

        算法思想描述:从头元素开始,不断选择后面元素中最小的元素放在已挑选排序的元素后面

          这里进行的是顺序排序:

         伪代码:

               For(i=1:n-1)

                     j=i;

                     for(k=i+1:n)

                        if(A[k]<A[j]) 

                           j=k;

                        k++;

                     swap(a[i],A[j]);

      算法复杂度:O^2;

3.冒泡排序(Bubble-sort)

      输入条件:一个乱序的n个元素的数组

      自然语言描述:依次比较相邻的两个数组,保证更大的数在后面,这个操作的结果是将最大的数字交换到了最后面,每次操作都从头元素开始,到终点结束,终点随每次操作逐渐向前移动一个元素。

      伪代码:

           For(i=0:n-1)

              For(j=0:n-i-1)

                    If(A[j]>A[j+1])

                          Swap(A[j],A[j+1];

      为了避免在已经排序提前完成的情况下,进行多余的操作,可进行改进如下:

                Exchange=true;

                For(i=0:n-1)

                   If(exchange==false) break;

                     Exchange=true;

                   For(j=0:n-i-1)

                        If(A[j]>[A[j+1]]

                            Swap(A[j],A[j+1]);

                            Exchange=true;

4.分治排序(Mergesort)

        输入条件:一个乱序的n个元素的数组A[]

        思想描述:使用递归方法对数组不断对半分割,分割到最后(即一个数时便不能再分割),这时开始递归回溯进行合并,合并时借助另一个数组B[],将合并后的一段元素存储在其中相应的位置,最后复制回来,逐渐回溯到整个数组,得到排序的数组

        伪代码:

                Mergesort(A,i,j)

                    K=(i+j)/2;

                    Mergesort(A,i,k)

                    Mergesort(A,k+1,j)

                    l=i;h=k+1;t=i;

                   While(l<=k&&h<=j)

                        If(A[l]<A[h])B[t]=A[l];l++;t++;

                        Else  B[t]=A[h];h++;t++;

                    If(l<=k)//如果前一半的还有剩余元素

                        For(v=l:k)

                           B[t]=A[v];t++;

                      If(h<=j)//如果后半还有剩余元素

                         For(v=h:j)

                           B[t]=A[v];t++;

             For(v=i:j)//将排序后的这一段元素复制到原数组中

                 A[v]=B[v];

5.快速排序(Quicksort)----很经典也很常用的排序算法

         输入条件:一个乱序的n个元素的数组      

思想描述:借鉴分治的原理,对每一段元素选取最后一个元素作为中间数,经过不断的交换,最终保证该数前面的元素更小,后面的元素更大,不断深入进行直到最底层,即只剩余一个数,这时便得到了排序后的数组

  伪代码:

    Quicksort(A,p,r)

       If(p<r)     

                     q=Partition(A,p,r)

                      Quicksort(A,p,q-1)

                      Quicksort(A,q+1,r)

             Partition(A,p,r)

                 x=A[r];

                 i=p-1;

                  for(j=p;j<r;j++)

                      if(A[j]<=x)

                            i++;

                            swap(A[j],A[i]);

                 swap(A[r],A[i+1];

                 return i+1;

6.堆排序(Heap_sort)---也很重要

      输入条件:一个乱序的n个元素的数组,按照数组顺序排列成一个二叉树  

     算法思想:

         调整堆(Max_Heapify—核心操作):从某一个结点开始 ,比较该结点,左结点,右结点,将该结点与最大值的结点交换,交换后可能会破环每一个节点比他的子节点更大的性质,所以要从刚才找到的结点处往下进行,循环此操作

         Max_Heapify(A,i)

            l=left(i);r=Right(i);//记录左右结点的数组下标一般:l=i*2;r=i*2+1

             if(l<Hsize(A)&&A[l]>A[i])

                     max=l;

              else

                     max=i;

            if(r<Hsize(A)&&A[r]>A[max])

                   max=r;

             if(max!=i)

                    swap(A[max],A[i])

                    Max_Heapify(A,max);

        中间方法:Build_max_heapify(A)

                Hsize=len(A);

                For(i=len(A)/2:1)

                    Max_heapify(A,i);

堆排序思想:先进行一次堆调整,使其满足堆性质,再从尾部到第二个元素每次执行:当前元素与堆顶元素交换,大小减小,从顶部进行堆调整

         Heap_sort(A)

              Bulid_max_heapify();

              For(i=len(A) to 2

                  Swap(A[1],A[i])

                  Hsize=Hsize-1;

                  Max_heapify(A,1);

剩余排序方法:统计排序(Counting Sort),线性排序(radix sort),桶排序(Bucket Sort)相对简单,就不再详细说明了


猜你喜欢

转载自blog.csdn.net/sinat_37926416/article/details/80049397