各种排序算法总结

1:合并排序

    合并排序算法使用分治策略实现对n个元素进行排序的算法。其基本思想是:将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最后总将排好序的子集合合并成所要求的排好序的集合。算法描述如下:

 void MergeSort(Typr a[],int left,int right)

{

               if(left<right){         //至少有两个元素

                        int i=(left+right)/2;            //取中点

                        MergeSort(a,left,i);

                        MergeSort(a.i+1,right);

                        Merge(a,b,left,i,right);   //合并到数组b

                        Copy(a,b,left,right);    //复制回数组a

               }

}

void Merge(Type c[],Type d[],int l,int m,int r)

{

              int i=l,j=m+1,k=1;

              while((i<=m)&&(j<=r))

              {

                     if(c[i]<=c[j])    d[k++]=c[i++];

                     else d[k++]=c[j++];

              }

              if(i>m)   for(int q=j;q<=r;q++)    d[k++]=c[q];

              else for(int q=i;q<=m;q++)             d[k++]=c[q];

}

时间复杂度:O(nlgn)

2:插入排序

    插入排序比较简单,算法描述如下:

   for j=2 to A.length

       key=A[i];

       i=j-1;

       while i>0 and A[i]>k

             A[i+1]=A[i];

             i--;

        A[i+1]=key;

时间复杂度:O(n²)

3:冒泡排序:  O(n²)

每次相邻的两个数据进行比较,大的向下沉,小的向上升,像水中的气泡一样。 1 for(int i=0;i<n;i++)

for(int i=0;i<n;i++)
{
int k=i;
for(int j=i+1;j<n;j++)
{
if(A[j]<A[k]) k=j;
}
swap(A[i],A[k]);
}

4:选择排序:O(n²)

1 for(int i=0;in<n;i++)
2 {
3       for(int j=i+1;j<n;j++)
4      {
5             if(A[i]>A[j])     swap(A[i],A[j]);
6      }
7 
8 }

5:堆排序:①把数组调整成一个最大堆  (从A[n/2]...1进行调整) A[i]的做节点是A[2i],右节点是A[2i+1]

                ②每次把对顶元素A[0]和A[n]进行交换,A[0]放到了正确的位置,然后n--,调整堆使其仍然成为一个最大堆重复②的操作直到得到结果

                时间复杂度:O(nlgn)

6:快速排序:就不说什么了,时间复杂度O(nlgn)

       

 1 void QuickSort(Type a[],int p,int r)
 2 {
 3         if(p<r)
 4         {
 5              int q=Partition(a,p,r);
 6              QuickSort(a,p,q-1);
 7              QuickSort(aa,q+1,r);
 8         }
 9 }
10 
11 
12 int Partition(Type a[],int p,int r)
13 {
14       int i=p,j=r+1;
15       Type x=a[p];
16       while(true)
17       {
18               while(a[++i]<x&&i<r);
19               while(a[--j]>x);
20               if(i>=j)     break;
21               Swap(a[i],a[j]);
22       }
23       a[p]=a[j];
24       a[j]=x;
25       return j;
26 }

////线性时间排序

  计数排序、计数排序、桶排序

  计数排序:假设每个输入元素都是在0到k区间内的一个整数,当k=O(n)时,排序运行的时间Θ(n)

  基数排序基本思想:对每一个输入元素x,确定小于x的元素的个数。利用这一信息,就可以直接把x放到它在输出数组中的位置上了。

  伪代码:假设输入时一个数组A[1..n],A.length=n。我们需要两个数组:B[1..n]存放排序的输出,C[0..k]提供临时存储空间。

  for i=0 to k          //c的值全置0

        c[i]=0;

  for j=1 to A.length        //c[i]等于i的元素的个数

        c[A[j]]=C[A[j]]+1

  for  i=1 to k                    //c[i]记录有多少元素是小于等于i的

        c[i]=c[i]+c[i-1]

  for j=A.length  downto 1

        B[c[A[j]]]=A[j]

        c[A[j]]=C[A[j]]-1

     

 桶排序:假设输入数据服从均匀分布,平均情况下它的时间代价为O(n)

伪代码:假设输入是一个含有n个元素的数组A,切每个A[i]满足0<=A[i]<1一个临时数组B[0..n-1]来存放链表,并假设存在一种用于维护这些链表的机制

n=A.length
let  B[0..n-1] be a new array
for i=0 to n-1
       make B[i]an empty list          //各个桶初始化为空
for i=1 to n
       insert A[i] into list B[nA[i]]         //把数据插入到各个桶中
for i=0 to n-1
       sort list B[i] with  insertion sort  //用插入排序对桶中的节点进行排序
concatenate  lists B[0],B[1]...B[n-1]together in order    //链接各个桶中的元素

  

原文地址:https://www.cnblogs.com/sqxw/p/3974541.html