1. 程式人生 > >5 種排序演算法--C語言連結串列

5 種排序演算法--C語言連結串列


原始碼地址 GitHub:https://github.com/GYT0313/C-DataStructure/blob/master/sortIn5.c

包括:

  1. 氣泡排序
  2. 快速排序
  3. 選擇排序
  4. 插入排序
  5. 希爾排序

執行:

注意:快速排序的核心程式碼應該沒有問題,但是不知道為什麼連結串列長度的值MAX會跑到連結串列中,找了半天沒找出來!!!
在這裡插入圖片描述

程式碼:

#include <stdio.h>
#include <stdlib.h>
#define  MAX   8 /*線性表的最大長度*/

typedef int ElemType; /*資料元素型別*/
/*順序表型別定義*/
typedef  struct
{
	 ElemType  data[MAX];
     int  length;  /*當前表的長度*/
} SeqList;

/* 初始化 */
SeqList *InitSeqlist()
{
    SeqList *L;
    L = (SeqList *)malloc(sizeof(SeqList));
    L->length = 0;

    return L;
}

/* 輸入 */
void input(SeqList *L)
{
    int i;

    srand( time(NULL) );
    for ( i=0; i<MAX; i++ )
    {
        L->data[i] = rand()%100;
        L->length++;
    }
}


/* 輸出 */
void output(SeqList *L)
{
    int i;

    for ( i=0; i<MAX; i++ )
        printf("%-4d", L->data[i]);

    printf("\n\n");
}



/* 氣泡排序  O(n^2) */
void BubbleSort( SeqList *L )
{
    int i, j, flag, tmp;

    for ( i=1; i<L->length; i++ )   /* 迴圈N-1次 */
    {
        flag = 0;   /* 標誌位 */

        for ( j=0; j<L->length-i; j++ )
        {
            if ( L->data[j] > L->data[j+1] )
            {
                flag = 1;
                tmp = L->data[j];
                L->data[j] = L->data[j+1];
                L->data[j+1] = tmp;
            }
        }
        if ( flag == 0 )
            return ;
    }
}


/* 快速排序  O(nlog2^n) */
void QuickSort( SeqList *L, int s, int t )
{
    int i, j, tmp;

    i = s;
    j = t;
    tmp = L->data[i];

    if ( s<t )
    {
        while ( i != j )
        {
            /* 右 */
            while ( i<j && L->data[j] >= tmp )    /* 右分割槽a[j] >= tmp ,繼續向左掃描 */
                j--;
            if ( i<j && L->data[j] < tmp )        /* 有分割槽a[j] < tmp, 賦值,並轉向左分割槽 */
                L->data[i++] = L->data[j];
            /* 左 */
            while ( i<j && L->data[i] <= tmp )
                i++;
            if ( i<j && L->data[i] > tmp )
                L->data[j--] = L->data[i];
        }
        L->data[i] = tmp;
        /* 遞迴呼叫 */
        QuickSort( L, s, i-1 );
        QuickSort( L, i+1, t );
    }
}

/* 選擇排序  O(n ^2) */
void selectSort( SeqList *L )
{
    int i, j, min, tmp;     /* 該次迴圈最小值下標  */

    for ( i=0; i<L->length-1; i++ )
    {
        for ( j=i+1, min=i; j<L->length; j++ )
        {
            /* 若最小值為a[min] 則重新賦值min */
            if ( L->data[j] < L->data[min] )
                min = j;
        }
        /* 判斷 a[i] 是否是最小值,若不是則重新賦值 */
        if ( min != i )
        {
            tmp = L->data[i];
            L->data[i] = L->data[min];
            L->data[min] = tmp;
        }
    }
}

/* 插入排序 O(n^2) */
void InsertSort( SeqList *L )
{
    int i, j, tmp;

    /* i =1, 第一個資料作為有序對,其餘資料作為無序對 */
    for ( i=1; i<L->length; i++ )
    {
        tmp = L->data[i];   /* tmp 為待排資料 */
        j = i-1;    /* j指向待排資料的前一個數據 */
        /* 迴圈找出待排資料的位置,同時又有資料的後移 */
        while ( j>=0 && tmp < L->data[j] )
        {
            L->data[j+1] = L->data[j];
            j--;
        }
        L->data[j+1] = tmp;     /* j+1 為帶插入資料的位置 */
    }
}

/* 希爾排序  O(n^(2/3) */
void ShellSort( SeqList *L )
{
    int d, i, j, tmp;

    /* 每次以 d 為間距進行分組 */
    for ( d=L->length/2; d>0; d/=2 )
    {
        /* 每次進行每組的一個數據的排序(分時) */
        for ( i=d; i<L->length; i++ )
        {
            tmp = L->data[i];
            /* 直接排序,從後往前 */
            for ( j=i-d; j>=0 && tmp<L->data[j]; j-=d )
            {
                L->data[j+d] = L->data[j];
            }
            L->data[j+d] = tmp;     /* 因為上層for迴圈跳出多執行了一次 j-d */
        }
    }
}


/* 選單 */
int menu()
{
    int choice;

    printf("               |****************順序表排序操作************|\n");
    printf("               |                 1. 氣泡排序法            |\n");
    printf("               |                 2. 快速排序法            |\n");
    printf("               |                 3. 選擇排序法            |\n");
    printf("               |                 4. 插入排序法            |\n");
    printf("               |                 5. 希爾排序              |\n");
    printf("               |                 0. 退出                  |\n");
    printf("               |******************************************|\n");

    do{
        printf("請輸入(0~5): ");
        scanf("%d", &choice);
    }while( choice < 0 || choice > 5 );

    return choice;
}


void form()
{
    SeqList *L;
    int flag=1;

    while ( flag )
    {
        switch( menu() )
        {
        case 1: /* 1. 氣泡排序法 */
            printf("\t\t氣泡排序:\n");
            L = InitSeqlist();
            input( L );
            printf("\n\tBefore sort: \n");
            output( L );
            BubbleSort( L );
            printf("\tSort:\n");
            output( L );
            printf("\n");
            system("pause"); //暫停
            system("cls"); //清屏
            break;
        case 2: /* 2. 快速排序法 */
            printf("\t\t快速排序:\n");
            L = InitSeqlist();
            input( L );
            printf("\n\tBefore sort: \n");
            output( L );
            QuickSort( L, 0, MAX );
            printf("\tSort:\n");
            output( L );
            printf("\n");
            system("pause"); //暫停
            system("cls"); //清屏

            break;
        case 3: /* 3. 選擇排序法 */
            printf("\t\t選擇排序:\n");
            L = InitSeqlist();
            input( L );
            printf("\n\tBefore sort: \n");
            output( L );
            selectSort( L );
            printf("\tSort:\n");
            output( L );
            printf("\n");
            system("pause"); //暫停
            system("cls"); //清屏

            break;
        case 4: /* 4. 插入排序法 */
            printf("\t\t插入排序:\n");
            L = InitSeqlist();
            input( L );
            printf("\n\tBefore sort: \n");
            output( L );
            InsertSort( L );
            printf("\tSort:\n");
            output( L );
            printf("\n");
            system("pause"); //暫停
            system("cls"); //清屏

            break;
        case 5: /* 5. 希爾排序 */
            printf("\t\t希爾排序:\n");
            L = InitSeqlist();
            input( L );
            printf("\n\tBefore sort: \n");
            output( L );
            ShellSort( L );
            printf("\tSort:\n");
            output( L );
            printf("\n");
            system("pause"); //暫停
            system("cls"); //清屏

            break;
        case 0: /* 0. 退出 */
            flag = 0;
        }
    }
}



int main()
{
    form();

    return 0;
}