交换类冒泡排序(Bubble Sort) O(n2)O(n^2)O(n2)最简单的一种排序算法。先从数组中找到最大值(或最小值)并放到数组最左端(或最右端),然后在剩下的数字中找到次大值(或次小值),以此类推,直到数组有序排列。void ...
 
                
交换类
- 冒泡排序(Bubble Sort) O(n2)
最简单的一种排序算法。先从数组中找到最大值(或最小值)并放到数组最左端(或最右端),然后在剩下的数字中找到次大值(或次小值),以此类推,直到数组有序排列。
void BubbleSortPlus(SqList L)
{
    int i, j, t, flag;
    flag = TRUE;
    for(i = 1; i <= L.length - 1 && flag; i++)
        for(j = 1; j <= L.length - 1 - i; j++)
        {
            flag = FALSE;
            if(L.elem[j] > L.elem[j+1])
            {
                t = L.elem[j];
                L.elem[j] = L.elem[j+1];
                L.elem[j+1] = t;
                flag = TRUE;
            }
        }
}
- 快速排序(Quick Sort)O(nlgn)(平均,最坏情况为冒泡排序)
快速排序的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,已达到整个序列有序。一趟快速排序的具体过程可描述为:从待排序列中任意选取一个记录(通常选取第一个记录)作为基准值,然后将记录中关键字比它小的记录都安置在它的位置之前,将记录中关键字比它大的记录都安置在它的位置之后。这样,以该基准值为分界线,将待排序列分成的两个子序列。
void QuickSort(SqList L)
{
    QSort(L, 1, LENGTH);
}
void QSort(SqList &L, int low, int high)
{
    int pivotloc;
    if(low < high)
    {
        pivotloc = Partition(L, low, high);
        QSort(L, low, pivotloc - 1);
        QSort(L, pivotloc + 1 , high);
    }
}
int Partition(SqList &L, int low, int high)
{
    L.elem[0] = L.elem[low];
    while(low < high)
    {
        while(low < high && L.elem[high] >= L.elem[0])
        {
            high--;
        }
        L.elem[low] = L.elem[high];
        while(low < high && L.elem[high] <= L.elem[0])
        {
            low++;
        }
        L.elem[high] = L.elem[low];
    }
    L.elem[low] = L.elem[0];
    return low;
}
插入类
- 直接插入排序(Straight Insertion Sort) O(n2)
插入排序的基本思想就是将无序序列插入到有序序列中。例如要将数组arr=[4,2,8,0,5,1]排序,可以将4看做是一个有序序列(图中用蓝色标出),将[2,8,0,5,1]看做一个无序序列。无序序列中2比4小,于是将2插入到4的左边,此时有序序列变成了[2,4],无序序列变成了[8,0,5,1]。无序序列中8比4大,于是将8插入到4的右边,有序序列变成了[2,4,8],无序序列变成了[0,5,1]。以此类推,最终数组按照从小到大排序。

void InsertSort(SqList L)
{
    int i, j;
    
    for(i = 2; i <= L.length; i++)
    {
        if(L.elem[i] < L.elem[i-1])
        {
            L.elem[0] = L.elem[i];
            L.elem[i] = L.elem[i-1];
            for(j = i - 2; L.elem[0] < L.elem[j]; j--)
            {
                L.elem[j+1] = L.elem[j];
            }
            L.elem[j+1] = L.elem[0];
        }
    }
}
- 希尔排序(Shell Sort) O(n23?)(较好情况)
希尔排序(Shell Sort)在插入排序算法的基础上进行了改进,算法的时间复杂度与前面几种算法相比有较大的改进。其算法的基本思想是:先将待排记录序列分割成为若干子序列分别进行插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行一次直接插入排序。

void ShellSort(SqList L)
{
    int i, j, dk = L.length;
    
    do
    {
        dk = dk / 3 + 1;
        for(i = dk + 1; i <= L.length; i++)
        {
            if(L.elem[i] < L.elem[i-dk])
            {
                count1++;
                L.elem[0] = L.elem[i];  //L.elem[0]不是哨兵
                L.elem[i] = L.elem[i-dk];
                for(j = i - 2 * dk; j > 0 && L.elem[0] < L.elem[j]; j--)
                {
                    L.elem[j+dk] = L.elem[j];
                }
                L.elem[j+dk] = L.elem[0];
            }
        }
    }while(dk > 1);
}
选择类
- 简单选择排序(Simple Selection Sort) O(n2)
每一趟在n-i+1(i=1,2,…,n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。
void InsertSort(SqList L)
{
    int i, j;
    for(i = 2; i <= L.length; i++)
    {
        if(L.elem[i] < L.elem[i-1])
        {
            L.elem[0] = L.elem[i];
            L.elem[i] = L.elem[i-1];
            for(j = i - 2; L.elem[0] < L.elem[j]; j--)
            {
                L.elem[j+1] = L.elem[j];
            }
            L.elem[j+1] = L.elem[0];
        }
    }
}
- 堆排序(Heap Sort) O(nlgn)
堆的定义如下: n个元素的序列{k1, k2, … , kn}当且仅当满足一下条件时,称之为堆。
??????ki??k2i?ki??k2i+1??or(i=1,2,...,?n/2?)?ki??k2i?ki??k2i+1??
堆排序(Heap Sort)是利用堆进行排序的方法。其基本思想为:将待排序列构造成一个大顶堆(或小顶堆),整个序列的最大值(或最小值)就是堆顶的根结点,将根节点的值和堆数组的末尾元素交换,此时末尾元素就是最大值(或最小值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次大值(或次小值),如此反复执行,最终得到一个有序序列。

void HeapSort(SqList L)
{
    int i, t;
    for(i = L.length / 2; i > 0; i--) //建堆
        HeapAdjust(L, i, L.length);
    for(i = L.length; i > 1; i--)
    {
        t = L.elem[1];
        L.elem[1] = L.elem[i];
        L.elem[i] = t;
        HeapAdjust(L, 1, i - 1);
    }
}
void HeapAdjust(SqList &L, int s, int m)
{
    int rc = L.elem[s], j;
    for(j = 2 * s; j <= m; j *= 2)
    {
        if(j < m && L.elem[j] < L.elem[j+1])
            j++;
        L.elem[s] = L.elem[j];
        s = j;
    }
    L.elem[s] = rc;
}
归并类
- 归并排序(Merge Sort) O(nlgn)(平均、最佳)
“归并”的含义是将两个或两个以上的有序序列组合成一个新的有序表。假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到?n/2?个长度为2(或者是1)的有序子序列,再两两归并。如此重复,直到得到一个长度为n的有序序列为止。这种排序方法称为2-路归并排序。

void MergeSort(SqList L)
{
    MSort(L, 1, L.length);
}
void MSort(SqList &L, int low, int high)
{
    int mid;
    if(low < high)
    {
        mid = (low + high) / 2;
        MSort(L, low, mid);
        MSort(L, mid + 1, high);
        Merge(L, low, mid, high);
    }
}
void Merge(SqList &L, int low, int mid, int high)
{
    int m, n, i, j;
    m = mid - low + 1;
    n = high - mid;
    int M[m], N[n];
    for(i = 0; i < m; i++)
        M[i] = L.elem[low+i];
    for(j = 0; j < n; j++)
        N[j] = L.elem[mid+j+1];
    i = j = 0;
    while(i < m && j < n)
    {
        if(M[i] <= N[j])
            L.elem[low++] = M[i++];
        else
            L.elem[low++] = N[j++];
    }
    while(i < m)
    {
        L.elem[low++] = M[i++];
    }
    while(j < n)
    {
        L.elem[low++] = N[j++];
    }
}
本文标题为:排序算法(C语言版)
 
				
         
 
            
        基础教程推荐
- C/C++ Qt StatusBar底部状态栏应用教程 2023-01-10
- 如何告诉 MinGW 链接器不要导出所有符号? 2022-10-07
- 使用VS2022开发在线远程编译部署的C++程序(图文详解) 2023-01-15
- C语言实现简易停车场管理系统 2023-03-13
- C++类和对象到底是什么 2022-11-12
- C语言文件操作与相关函数介绍 2023-06-13
- C语言预编译#define(预处理) 2023-04-03
- 使用C/C++读写.mat文件的方法详解 2023-03-05
- C++高级数据结构之并查集 2023-04-20
- 漫画讲解C语言中最近公共祖先的三种类型 2023-01-01
 
    	 
    	 
    	 
    	 
    	 
    	 
    	 
    	 
						 
						 
						 
						 
						 
				 
				 
				 
				