排序算法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法相关的知识,希望对你有一定的参考价值。

排序算法有很多种,并在实际编程过程中用的非常广泛。常用的排序算法有:插入排序算法,选择排序算法,冒泡排序算法,快速排序算法,归并排序算法,希尔排序算法,堆排序算法。

各种排序算法的时间复杂度:

1.冒泡法:  O(n*n)
2.直接插入排序:O(n*n)
3.选择排序:O(n*n)
4.快速排序:平均时间复杂度log2(n)*n,所有内部排序方法中最高好的
5.归并排序:log2(n)*n
6.堆排序:log2(n)*n
7.希尔排序:算法的复杂度为n的1.2次幂

头文件:

/***************************************************************************************************** 
 *Copyright:Yue Workstation 
 * 
 *FileName:Sort.h 
 * 
 *Function:排序相关数据定义和函数声明 
 * 
 *Author:Abel Lee 
 * 
 *CreateOn:2012-2-9 
 * 
 *Log:2012-2-9 由Abel Lee创建 
 *****************************************************************************************************/ 

#ifndef SORT_H 
#define SORT_H 

#include "global.h" 
#include <time.h> 

#define MAXSIZE 20 

typedef int InfoType; 
#define EQ(a,b) ((a) == (b)) 
#define LT(a,b) ((a) < (b)) 
#define LQ(a,b) ((a) <= (b)) 

#ifdef STRING 
#define EQ(a,b) (!strcmp(a,b)) 
#define LT(a,b) (strcmp(a,b) < 0) 
#define LQ(a,b) (strcmp(a,b) <= 0) 
#endif 

typedef struct 
{ 
    ElemType key; 
    InfoType otherinfo; 
}ReadType; 

typedef struct 
{ 
    ReadType r[MAXSIZE+1]; 
    int length; 
}SortList; 

typedef SortList HeapType;//堆采用顺序表存储表示 

#define MAX_NUM_OF_KEY 8  //关键字项数最大值 

void InitSortList(SortList *L); 
void PrintSortList(SortList L); 
int InsertSort(SortList *L); 
int BubblingSort(SortList *L); 
int SelectSort(SortList *L); 
int QuickSort(SortList *L, int low, int high); 
void MergeSort(int a[], int size); 
int ShellSort(SortList *L, int dlta[], int t); 
int HeapSort(HeapType *L); 

#endif

源文件:

/***************************************************************************************************** 
 *Copyright:Yue Workstation 
 * 
 *FileName:Queue.c 
 * 
 *Function:排序基本算法 
 * 
 *Author:Abel Lee 
 * 
 *CreateOn:2012-2-9 
 * 
 *Log:2011-2-9 由Abel Lee创建 
 *****************************************************************************************************/ 

#include "../inc/Sort.h" 

/**************************************************************************************************** 
 *Function Name: InsertSort 
 * 
 *Function:初始化排序队列 
 * 
 *Parameter: L:排序队列 
 * 
 *Return Value:无 
 * 
 *Author:Abel Lee 
 * 
 *Log:2011-2-10 
 ***************************************************************************************************/ 
void InitSortList(SortList *L) 
{ 
    int i = 0; 

    srand((unsigned)time(NULL)); 
    for(i = 1;i <= MAXSIZE; i++) 
    { 
        L->r[i].key = rand()%100; 
    } 

    L->length = 20; 
    return; 
} 

/**************************************************************************************************** 
 *Function Name: PrintSortList 
 * 
 *Function:打印排序队列 
 * 
 *Parameter: L:排序队列 
 * 
 *Return Value:无 
 * 
 *Author:Abel Lee 
 * 
 *Log:2011-2-10 
 ***************************************************************************************************/ 
void PrintSortList(SortList L) 
{ 
    int i = 0; 

    for(i = 1;i <= MAXSIZE; i++) 
    { 
        printf("%d--",L.r[i].key); 
    } 
    putchar(‘
‘); 
    return; 
} 

/**************************************************************************************************** 
 *Function Name: InsertSort 
 * 
 *Function: 插入排序算法(插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。) 
 * 
 *Parameter: L:排序数据指针 
 * 
 *Return Value:成功返回0,失败返回-1 
 * 
 *Author:Abel Lee 
 * 
 *Log:2011-2-10 
 ***************************************************************************************************/ 
int InsertSort(SortList *L) 
{ 
    int i = 0; 
    int j = 0; 

    if(L == NULL) 
    { 
        perror("L is NULL!
"); 
        return -1; 
    } 

    for(i = 2; i<=L->length; i++) 
    { 
        if(LT(L->r[i].key, L->r[i-1].key)) 
        { 
            L->r[0] = L->r[i]; 
            L->r[i] = L->r[i-1]; 
            for(j=i-2; LT(L->r[0].key, L->r[j].key); j--) 
            { 
                L->r[j+1] = L->r[j]; 
            } 
            L->r[j+1] = L->r[0]; 
        } 
    } 
    return 0; 
} 

/**************************************************************************************************** 
 *Function Name: BubblingSort 
 * 
 *Function: 选择排序算法 
 * 
 *Parameter: L:排序数据指针 
 * 
 *Return Value:成功返回0,失败返回-1 
 * 
 *Author:Abel Lee 
 * 
 *Log:2011-2-21 
 ***************************************************************************************************/ 
int SelectSort(SortList *L) 
{ 
    int i = 0; 
    int j = 0; 
    ReadType temp; 

    if(L == NULL) 
    { 
        return -1; 
    } 

    for(i = 1; i <= L->length; i++) 
    { 
        for(j = i+1; j <= L->length; j++) 
        { 
            if(L->r[i].key > L->r[j].key) 
            { 
                temp = L->r[i]; 
                L->r[i] = L->r[j]; 
                L->r[j] = temp; 
            } 
        } 
    } 
    return 0; 
} 

/**************************************************************************************************** 
 *Function Name: BubblingSort 
 * 
 *Function: 冒泡排序算法 
 * 
 *Parameter: L:排序数据指针 
 * 
 *Return Value:成功返回0,失败返回-1 
 * 
 *Author:Abel Lee 
 * 
 *Log:2011-2-21 
 ***************************************************************************************************/ 
int BubblingSort(SortList *L) 
{ 
    int i = 0; 
    int j = 0; 
    ReadType temp; 

    if (L == NULL) 
    { 
        return -1; 
    } 

    for (i = 1; i <= L->length; i++) 
    { 
        for (j = 1; j < L->length; j++) 
        { 
            if (L->r[j].key > L->r[j+1].key) 
            { 
                temp = L->r[j]; 
                L->r[j] = L->r[j+1]; 
                L->r[j+1] = temp; 
            } 
        } 
    } 
    return 0; 
} 

/**************************************************************************************************** 
 *Function Name: QuickSort 
 * 
 *Function: 快速排序算法 
 * 
 *Parameter: L:排序数据指针 
 * 
 *Return Value:成功返回0,失败返回-1 
 * 
 *Author:Abel Lee 
 * 
 *Log:2011-2-21 
 ***************************************************************************************************/ 
static int Partition(SortList *L, int low, int high) 
{ 
    int flag = 0; 
    L->r[0] = L->r[low]; 
    flag = L->r[low].key; 
    while(low < high) 
    { 
        while(low < high && L->r[high].key >= flag) 
            high--; 
        if(low < high) 
            L->r[low] = L->r[high]; 
        while(low < high && L->r[low].key <= flag) 
            low++; 
        if(low < high) 
            L->r[high] = L->r[low]; 
    } 
    L->r[low] = L->r[0]; 
    return low; 
} 

int QuickSort(SortList *L, int low, int high) 
{ 
    int flag = 0; 

    if(low < high) 
    { 
        flag = Partition(L,low,high); 
        QuickSort(L,low,flag-1); 
        QuickSort(L,flag+1,high); 
    } 

    return 0; 
} 

/**************************************************************************************************** 
 *Function Name: MergeSort 
 * 
 *Function: 归并排序算法 
 * 
 *Parameter: a:要排序的数组 
 *           size:要排序的数组长度 
 * 
 *Return Value:成功返回0,失败返回-1 
 * 
 *Author:Abel Lee 
 * 
 *Log:2011-2-21 
 ***************************************************************************************************/ 
static void Merge(int a[], int b[], int low, int mid, int high) 
{ 
    int k = low; 
    int begin1 = low; 
    int end1 = mid; 
    int begin2 = mid + 1; 
    int end2 = high; 
    int q; 

    while(begin1 <= end1 && begin2 <= end2) 
    { 
        if(a[begin1] <= a[begin2]) 
            b[k++] = a[begin1++]; 
        else 
            b[k++] = a[begin2++]; 
    } 
    if(begin1 <= end1) 
        for( q = begin1; q <= end1; q++) 
            b[k++] = a[q]; 
    else 
        for(q = begin2; q <= end2; q++) 
            b[k++] = a[q]; 
} 

static void MergePass(int a[], int b[], int seg, int size) 
{ 
    int seg_start_ind = 0; 
    int j; 

    while(seg_start_ind <= size - 2 * seg) //#size - 2 * seg的意思是满足可两两归并的最低临界值#% 
    { 
        Merge(a, b, seg_start_ind, seg_start_ind + seg - 1, seg_start_ind + seg * 2 - 1); 
        seg_start_ind += 2 * seg; 
    } 
    //#如果一段是正好可归并的数量而另一段则少于正好可归并的数量#% 
    if(seg_start_ind + seg < size) 
        Merge(a, b, seg_start_ind, seg_start_ind + seg - 1, size - 1); 
    else 
        for(j = seg_start_ind; j < size; j++) //#如果只剩下一段或者更少的数量#% 
            b[j] = a[j]; 
} 

void MergeSort(int a[], int size) 
{ 
    int* temp = (int *)malloc(size); 
    int seg = 1; 
    while(seg < size) 
    { 
        MergePass(a, temp, seg, size); 
        seg += seg; 
        MergePass(temp, a, seg, size); 
        seg += seg; 
    } 
} 

/**************************************************************************************************** 
 *Function Name: RadixSort 
 * 
 *Function: 基数排序算法 
 * 
 *Parameter: L:排序数据指针 
 * 
 *Return Value:成功返回0,失败返回-1 
 * 
 *Author:Abel Lee 
 * 
 *Log:2011-2-21 
 ***************************************************************************************************/ 
int RadixSort() 
{ 
    return 0; 
} 

/**************************************************************************************************** 
 *Function Name: ShellSort 
 * 
 *Function: 希尔排序算法 
 * 
 *Parameter: L:排序数据指针 
 *           dlta:步长值数组 
 *           t:步长值数量 
 * 
 *Return Value:成功返回0,失败返回-1 
 * 
 *Author:Abel Lee 
 * 
 *Log:2011-2-21 
 ***************************************************************************************************/ 
static void ShellInsert(SortList *L,int dk) 
{ 
    int i = 0; 
    int j = 0; 

    for(i=dk; i<=L->length; i++) 
    { 
        if(LT(L->r[i].key,L->r[i-dk].key))//须将L->r[i]插入有序增量子表 
        { 
            L->r[0] = L->r[i];//暂时存在L.r[0] 
            for(j=i-dk; j>0 && LT(L->r[0].key,L->r[j].key);j-=dk) 
            { 
                L->r[j+dk] = L->r[j];//记录后移,查找插入位置 
            } 
            L->r[j+dk] = L->r[0];//插入 
        } 
    } 
} 
int ShellSort(SortList *L, int dlta[], int t) 
{ 
    int i = 0; 

    if(L == NULL) 
    { 
        return -1; 
    } 
    for(i = 0; i < t; i++) 
        ShellInsert(L,dlta[i]);//一趟增量为dlta[i]的插入排序 

    return 0; 
} 

/**************************************************************************************************** 
 *Function Name: HeapSort 
 * 
 *Function: 堆排序算法 
 * 
 *Parameter: L:排序数据指针 
 * 
 *Return Value:成功返回0,失败返回-1 
 * 
 *Author:Abel Lee 
 * 
 *Log:2011-2-22 
 ***************************************************************************************************/ 
//已知H->r[s...m]中记录的关键字除H->r[s].key之外均满足堆的定义,本函数调整H->r[s] 
//的关键字,使H->r[s...m]成为一个大堆顶(对其中记录的关键字而言) 
static int HeapAdject(HeapType *H, int s, int m) 
{ 
    ReadType rc; 
    int i = 0; 

    rc = H->r[s]; 
    for(i = 2*s; i <= m; i*=2)//沿key较大的孩子节点乡下筛选 
    { 
        if(i < m && LT(H->r[i].key,H->r[i+1].key)) 
        { 
            i++;//i为key较大的记录的下标 
            if(!LT(rc.key,H->r[i].key))//rc应插入在位置s上 
            { 
                break; 
            } 
            H->r[s] = H->r[i]; 
            s = i; 
        } 
    } 
    H->r[s] = rc;//插入 

    return 0; 
} 

int HeapSort(HeapType *H) 
{ 
    int i = 0; 
    ReadType rt; 

    for(i = H->length/2; i > 1; i--) 
    { 
        HeapAdject(H,i,H->length); 
    } 
    for(i = H->length; i > 1; i--) 
    { 
        //将堆顶记录和当前未经排序的记录交换 
        rt = H->r[1]; 
        H->r[1] = H->r[i]; 
        H->r[i] = rt; 

        HeapAdject(H,1,i-1);//将H->r[1...i-1]重新调整为打顶堆 
    } 
    return 0; 
}

以上是关于排序算法的主要内容,如果未能解决你的问题,请参考以下文章

算法排序之堆排序

快速排序-递归实现

从搜索文档中查找最小片段的算法?

在第6731次释放指针后双重免费或损坏

TimSort算法分析

以下代码片段的算法复杂度