自己关于排序的总结

所有排序的总结:

 

1、  插入排序

插入排序是最简单最直观的排序算法了,它的依据是:遍历到第N个元素的时候前面的N-1个元素已经是排序好的了,那么就查找前面的N-1个元素把这第N个元素放在合适的位置,如此下去直到遍历完序列的元素为止.

  插入排序是最简单最直观的排序算法了,它的依据是:遍历到第N个元素的时候前面的N-1个元素已经是排序好的了,那么就查找前面的N-1个元素把这第N个元素放在合适的位置,如此下去直到遍历完序列的元素为止.

  算法的复杂度也是简单的,排序第一个需要1的复杂度,排序第二个需要2的复杂度,因此整个的复杂度就是

  1 + 2 + 3 + ... + N = O(N ^ 2)的复杂度.

// 插入排序

void InsertSort(int array[], int length)

{

    int i, j, key;

 

    for (i = 1; i < length; i++)

    {

        key = array[i];

        // i之前大于array[i]的数据向后移动

        for (j = i - 1; j >= 0 && array[j] > key; j--)

        {

            array[j + 1] = array[j];

        }

        // 在合适位置安放当前元素

        array[j + 1] = key;

    }

}

 

 

2、选择排序:

每次确定一个数位,这个数位是后面所有数的最小值放到这个位置

Void SelectInsert(int *arr)

{     int i,j;

       int min,index;

       For(i=0;i<n-1;i++)

       {

For(j=i+1,index=j,min=arr[j]; j<n; j++)

              {

                     If(  arr[j]<min  )

                     {     min=arr[j] ;

                            index=j;                

                     }

}

int temp=arr[i];

arr[i]=arr[index];

arr[index]=temp;

}

}

 

3、堆排序:

//HEAP SORT 堆排序,用一个二插堆,大根堆即可

//heap[0]是临时元素,作临时变量用途;heap[1 -- n]是实际的大根堆的数据内存空间

 

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <time.h>

 

const int MAX=100004;

 

void swap(int &a,int &b)                  //注意传引用

{

     a^=b;

     b^=a;

     a^=b;

}

 

void buildheap(int* arr,int len)     //O( N*Lg(N) )

{

     int i,j,t;

     for( i=len/2;i>=1;i-- )              //从底往上进行构造                            

     {

         j=i;

         while(j<=len)

         {

              t=arr[j];

              if( j*2<=len && t < arr[j*2] )

                   t=arr[j*2];

              if( (j*2+1)<=len && t < arr[j*2+1] )

                   t=arr[j*2+1];

 

              if( t==arr[j*2] )

              {    swap( arr[j],arr[j*2] );

                   j=j*2;

                   continue;

              }

              else if( t==arr[j*2+1] )

              {    swap( arr[j],arr[j*2+1] );

                   j=j*2+1;

                   continue;

              }   

              else

                   break;                      //退出while

         }

 

     }

}

 

void adjustheap(int* arr,int l)

{

     int i,t;

     i=1;

     while(i<=l)

     {

         t=arr[i];

         if( (i*2)<=l && t < arr[i*2] )

              t=arr[i*2];

         if( (i*2+1)<=l && t < arr[i*2+1] )

              t=arr[i*2+1];

 

         if( t==arr[i*2] )

         {    swap( arr[i],arr[i*2] );

              i=i*2;

              continue;

         }

         else if( t==arr[i*2+1] )

         {    swap( arr[i],arr[i*2+1] );

              i=i*2+1;

              continue;

         }   

         else

              break;                      //退出while

     }

 

}

 

 

void heapsort(int* arr,int len)

{

     int i;

     buildheap(arr,len);

     for(i=len;i>=2;i--)

     {

         swap(arr[1],arr[i]);

         adjustheap(arr,i-1);             //i-1这个参数,很变态很无敌

     }

    

     for(i=1;i<len;i++)

         printf("%d ",arr[i]);

     printf("%d/n",arr[i]);

 

}

 

int main()

{

     int arr[MAX];

     srand(time(NULL));

 

     for(int i=0;i<100;i++)

         arr[i+1]=rand()%100;  

     heapsort(arr,100);

     getchar();

     return 0;

}

 

4、  归并排序:                                                      //N*lg(N) 复杂度,因为一层整个叶子是                                                                         //N,然后一共有lg(N)

int temp[MAX];                                     //因为有归并的过程,所以不是内排序,需要另外开辟这个存储数组空间

void merge(int* arr,int start,int mid,int end)

{                                                  //start~mid是排序好的mid+1~end也是排序好的,只要把这两部分合并起来即可

     int n1=mid-start+1;

     int n2=end-mid;

     int i,cnt;

     int i1=start,i2=mid+1;

     for(i=start,cnt=0;i<=end;i++)

     {

         if( i1>mid )

         {    temp[cnt++]=arr[i2];

              i2++;

              continue;

         }

         if( i2>end )

         {

              temp[cnt++]=arr[i1];

              i1++;

              continue;

         }

 

 

         if( arr[i1]>arr[i2] )

         {

              temp[cnt++]=arr[i2];

              i2++;

         }

         else

         {

              temp[cnt++]=arr[i1];

              i1++;

         }

     }

 

     for(i=start,cnt=0;i<=end;i++)

         arr[i]=temp[cnt++];

}

 

void mergesort(int* arr,int start,int end)     //归并排序

{

     if(start<end)                             //==的时候即不用继续mergesort

     {

         int mid=(start+end)>>1;

         mergesort(arr,start,mid);

         mergesort(arr,mid+1,end);

         merge(arr,start,mid,end);

     }

}

 

5、  快速排序:QSORT  注意那个桶倒来倒去的过程和办法即可

 

6、冒泡排序有个优化就是if(a[i]>a[i+1])的时候记录 i 的值temp,内层的循环只要循环到这个temp值即可,因为后面的是有序的。


总结上述的排序算法:

稳定的讨论就是说按照同样的数字进行原序的排序

 

自然选择排序和插入排序太慢,用起来不爽

那么就讨论下 归并,堆排和快排

 

快排有退化 就是O(N^2) 但是不用第一个,而是每次用随机算法选择数能改进这个算法的最坏复杂度,而且快排不稳定      

归并排序,是非内部排序,需要另外开辟空间处理,但是是稳定的,用来处理逆序数很强大

而堆排 是不稳定的,但是是内部排序,并且没退化,处理大数据来说非常好的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值