挑战程序设计(算法和数据结构)—排序

文章目录

          • 插入排序
          • 冒泡排序
          • 选择排序
          • 希尔排序
          • 归并排序
          • 快速排序
          • 计数排序

插入排序

稳定排序
O(N^2)
将未排序的头元素插入到已排序的元素中
特点:高速处理顺序较平整的数组,希尔排序的基础

void InsertSort(int a[], int N)
{
    for(int i=1; i=0 && a[j]>v)#j循环变量,用于在已排序部分寻找v的插入位置
        {
            a[j+1] = a[j];#相应元素后移
            j--;
        }
        a[j+1] = v;#插入到合适位置
    }
}
冒泡排序

稳定排序
O(N^2)
每一轮在未排序区比较相邻元素,筛选出最小元素到排序区尾

void BubbleSort(int a[], int N)
{
     int flag = 1, i = 0;#flag标记当前轮是否存在交换,若没有则结束排序。i表示未排序区的开头元素标记,从数组开头向末尾移动
     while(flag)
     {
         flag = 0;
         for(int j=N-1; j>i; j--)#对于未排序部分中相邻元素两两比较,从N-1开始,减少到i+1结束
         {
             if(a[j]
选择排序

不稳定排序
O(N^2)
在未排序区选出最小元素,放入已排序区尾

void SelectSort(int a[], int N)
{
      for(int i=0; i
希尔排序

O(N^1.25)
不同间隔的插入排序,最后一定以1为间隔来一次插入排序
特点:比较次数多,交换次数少

vector G;#间隔序列
void InsertSort(int a[], int N, int g)#以g为间隔的插入排序
{
    for(int i=g; i=0 && a[j]>v)
        {
            a[j+g] = a[j];
            j-=g;
            cnt++;
        }
        a[j+g] = v;
    }
}

void ShellSort(int a[], int N)
{
       //生成G序列
       int h  = 1;
       while(h=0; i--)#重复G序列次
       {
           InsertSort(a, N, G[i]);
       }
}
归并排序

O(Nlog(N)) (O(log(N))为分割,O(N)为归并)
稳定
特点:高效且稳定,但要占用额外的内存空间(除了输入数据)。

void Merge(int S[], int left, int right, int mid)//归并(归并时比较排序)
{
    int n1 = mid-left, n2 = right-mid;//以mid为界限,分割为两个数组
    for(int i=0; ib[kb])//升序排列,一定为大于,保证了稳定排序
        {
            S[k++] = b[kb++];
        }
        else
        {
            S[k++] = a[ka++];
        }
        Count++;//计数
    }
}

void MergeSort(int S[], int left, int right)//用于分割数组,分别排序(分治)
{
    if(left+1
快速排序

O(Nlog(N))(平均)O(N^2)(最坏)
不稳定
特点:内部排序,不占用额外内存。技巧在于基准x的选择(随机选择、任选几个取其平均)。

void swap(int *x, int *y)//交换函数
{
    int temp = *x;
    *x = *y;
    *y = temp;
}
int Partition(int A[], int p, int r)//分割函数(每次排好一个元素的位置)
{
    int x = A[r];//分割的标准,大于x 的为一部分,其余的为另一部分
    int i=p-1;//下标小于等于i的元素不大于x
    for(int j=p; j
计数排序

O(n+k)(n是排序数组的长度,k是计数数组的长度,即排序数组中最大值)
稳定
特点:线性时间排序,所用时间和空间均与原数组的最大值成正比。

int A[MaxA], B[MaxB], C[MaxC];
//A原数组。C计数数组m,C[i]表示小于等于i的A中元素的个数。B排序后的数组。
void CountingSort(int A[], int n, int k)
{
    memset(C, 0, sizeof(C));//初始化为0
    for(int i=0; i=0; i--)//倒序(保证稳定排休)
    {
        B[C[A[i]]] = A[i];//注意:输出B时,要从1到n输出,因为C[A[i]](1-n)表示小于等于A[i]的元素的个数,其值一定大于0
        C[A[i]]--;
    }
}

你可能感兴趣的:(挑战程序设计-算法和数据结构)