• 排序算法总结


    一、插入排序

    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("
    ");
         }
         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);
            }
    }
  • 相关阅读:
    oracle 函数WMSYS.WM_CONCAT()的用法(行转列) 老猫
    PL/SQL 数独 九宫图 老猫
    oracle10g rman backup and recover 老猫
    Oracle SQL的优化 老猫
    Oracle数据库中的字符处理技巧总结 老猫
    WITH分析函数 老猫
    30套JSP网站源代码合集
    Java获取系统信息(cpu,内存,硬盘,进程等)的相关方法
    [原]Web Service学习
    常用Web Service汇总(天气预报、时刻表等)
  • 原文地址:https://www.cnblogs.com/rickhsg/p/3772648.html
Copyright © 2020-2023  润新知