排序算法总结

一、插入排序

1.直接插入排序

算法稳定,时间复杂度为O(n^2),空间移动复杂度为O(n2)

如果序列是有序的,最好的时间复杂度为O(n)

即该算法与初始数据的排序序列有关。

void insertSort(int data[],int n)
{
  for(int i=1;i<n;i++)
  {
      int j = i - 1;
      int temp = data[i];
      while(j>=0&&data[j]>temp) 
     {
         data[j+1] = data[j];
         j--;
     }  
     data[j+1] = temp;  
  }    
}

2.折半插入排序

查找插入位置采用折半查找法。

算法稳定,时间复杂度为O(nlog2n),空间移动复杂度为O(n2)

折半插入算法与初始数据的顺序是有关系的。数据有序的时候,折半查找的效率反而降低。

void BinaryinsertSort(int data[],int n)
{
  for(int i=1;i<n;i++)
 {
      int left = 0;
      int right = i-1;
      int temp = data[i];
      while(left<=right)
      {
           int mid = (left+right)/2 ;
           if(data[mid]>temp)              //判断是否影响稳定性。
rigth = mid - 1;
else left = mid + 1; } for(int j=i-1;j>=left;j--) data[j+1] = data[j]; data[left] = temp; } }

3.希尔排序

将待排数据分组,组内进行直接插入排序。逐步减小分组数,最后再整体进行直接插入排序。

希尔排序的时间复杂度为介于O(nlog2n)与O(n*n)之间,大约为O(n1.3);

希尔排序算法是不稳定的。

void  ShellSort(int data[],int n)
{
    int d = n/2;
    while(d>=1)
    {
        for(int k=0;k<d;k++)
         {
            for(int i=k+d;i<n;i+=d)
             {
                    int temp = data[i];
                    int j=i-d;
                    while(j>=k&&data[j]>temp)
                    {
                        data[j+d] = data[j];
                        j-=d;
                    }
                    data[j+d]=temp;
             }
        }
        d = d/2;
    }
}

 

二、交换排序

1.冒泡排序

时间复杂度为O(n*n),是稳定的排序算法。

其排序效果与初始序列的顺序有关系。

程序如下:

最原始的冒泡排序算法:

void BubbleSort(int data[ ],int n)
{
        for(int i=0;i<n-1;++i)
        {
            for(int j=1;j<n-i;++j)
            {
                    if(data[j-1]>data[j])
                    {
                            int temp = data[j-1];
                            data[j-1] = data[j];
                            data[j] = temp;
                    }
            }
        }
}

改进后的冒泡排序算法:

最好的情况先是数据序列本来就是有序的,只需要进行n-1次的比较,不需要进行交换。

即仅需要进行0次的交换。

void BubbleSort(int data[ ],int n)
{
        for(int i=0;i<n-1;++i)
        {
            int flag = 0;
            for(int j=1;j<n-i;++j)
            {
                    if(data[j-1]>data[j])
                    {
                            flag = 1;
                            int temp = data[j-1];
                            data[j-1] = data[j];
                            data[j] = temp;
                    }
            }
            if(0==flag)
                return;
        }
}

 

2.快速排序

分治法的思想,最坏的情况是待排数据时有序的时候,此时会造成轴元素的一侧子序列的长度为0,另一侧的长度为n,此时时间复杂度为O(n*n)

空间复杂度主要是递归调用的栈的开销,最好的时候是O(logn),最坏的情况是O(n).

平均的时间复杂度为:O(nlogn);

该算法是不稳定的。

大量数据的排序,最好使用快速排序。这样带来的促进效果会更加显著。

 

代码如下:

sort排序:

 

int partition(T data[],int left,int right)
{
    int p = data[left];
    while(left<=right)
   {
        while(left<=right&&data[left]<=p)
            left++;
        while(left<=right&&data[right]>=p)
            right--;
        if(left<right)
        {
            swap(data[left],data[right]);
            left++;right--;
        }
    }
    swap(p,data[right]);
    return right;
}

void quicksort(int data[],int left,int right)
{
    if(left<right)
    {
        int p = partion(data,left,right);
        quicksort(data,left,p-1);
        quicksort(data,p+1,right);
    }
}

或者

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void swap(int *a,int *b)
{
     int temp = *a;
     *a = *b; 
     *b = temp;
}
int partation(int data[],int left,int right)
{
     int p = data[left];
     int start = left;
     while(left<=right)
    {
         while(left<=right&&data[left]<=p)
              left++;
         while(left<=right&&data[right]>p)
             right--;
         if(left<right)
         {
             swap(&data[left],&data[right]);
             left++;right--;
         }
    }
    swap(&data[start],&data[right]);
    return right;
}
void quicksort(int data[],int left,int right)
{
    int p;
    if(left<right)
    {
        p = partation(data,left,right);
        quicksort(data,left,p-1);
        quicksort(data,p+1,right);
    }
}
int main()
{
     int n;
     int i;
     int arr[100];
     while(scanf("%d",&n)!=EOF)
     {
          for(i=0;i<n;i++)
          scanf("%d",&arr[i]);
          quicksort(arr,0,n-1);
          for(i=0;i<n;i++)
               printf("%d ",arr[i]);
          printf("\n");
     }
     return 0;
}
View Code

三、选择排序

1.简单选择排序

时间复杂度为O(n*n),空间复杂度为O(1)

不稳定的排序算法。

程序如下:

void SelectionSort(int data[ ],int n)
{
    for(int i=1;i<n;++i)
    {
          int k = i - 1;
          for(int j = i; j<n;++j)
           {
                if(data[j]<data[k])
                        k = j;
            }
            if(k!=i-1)
            {
                    swap(data[i-1],data[k]);
            }
}

 

2.堆排序

建堆的时间复杂度为O(n)

最大堆的调整函数为shiftdown()函数。

每次最多执行O(logn)次数据的交换,所以其时间复杂度为O(nlogn).

空间开销是O(1).

该算法是不稳定的。

四、归并排序

最坏的情况下的时间复杂度也为O(nlogn),算法是稳定的。

空间复杂度为O(n).

原始数据的排列情况对该排序算法的复杂度没有影响。

 

程序如下,如下的程序时二路归并排序,所谓的二路归并排序指的是,每次迭代都将待排序列分割为两个等长的子序列,

就称为二路归并排序:

合并一个序列中的两个有序的序列:

void Merg(int data[ ],int start,int mid,int end)
{
    int len1 = mid - start + 1;
    int len2 = end - mid;
    int i,j,k;
    for(k=start;k<end;++k)
    {
        if(i==len1 || j==len2)
            break;
        if(left[i]<=right[j])
            data[k]=left[i++];
        else
            data[k]=right[j++];
        while(i<len1)
            data[k++] = left[i++];
        while(j<len2)
            data[k++] = right[j++];
    }
}

//归并排序实现:

void MergSort(int data[ ],int start,int end)
{
        if(start < end)
        {
            int mid = (start + end)/2;
            MergSort(data,start,mid);
            MergSort(data,mid+1,end);
            Merg(data,start,mid,end);
        }
}

 

 

转载于:https://www.cnblogs.com/rickhsg/p/3772648.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值