欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言排序算法之桶排序解析

 更新時間:2023年10月30日 10:23:21   作者:有人_295  
這篇文章主要介紹了C語言排序算法之桶排序解析,桶排序Bucket?sort或所謂的箱排序,是一個排序算法,工作的原理是將數(shù)組分到有限數(shù)量的桶里,每個桶再分別排序,大部分是在分桶時,即插入時就排序了,需要的朋友可以參考下

1. 算法思想

桶排序(Bucket sort)或所謂的箱排序,是一個排序算法,工作的原理是將數(shù)組分到有限數(shù)量的桶里,每個桶再分別排序(大部分是在分桶時,即插入時就排序了)。

個人理解,適合數(shù)據(jù)比較集中排序,桶的數(shù)量適當(dāng)設(shè)置。

2. 實現(xiàn)原理

桶排序以下列程序進行:

  • 設(shè)置一個定量的數(shù)組當(dāng)作空桶子。
  • 尋訪序列,并且把項目一個一個放到對應(yīng)的桶子去。
  • 對每個不是空的桶子進行排序。
  • 從不是空的桶子里把項目再放回原來的序列中。

3. 動態(tài)演示

在這里插入圖片描述

(1)數(shù)據(jù)分桶

在這里插入圖片描述

(2)桶內(nèi)數(shù)據(jù)排序(大部分是在分桶時,即插入時就排序了)

在這里插入圖片描述

(3)然后連接就好了

4. 完整代碼

主要函數(shù)

插入函數(shù):void insert(BN* list, int value)
排序函數(shù):void bucket_sort(int* array, int size, int num)
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h> // rand() srand()
#include <time.h>   // time()

typedef struct BucketNode
{
    int                data;
    struct BucketNode* next;
} BN;

void displayL(BN* L);               // 輸出鏈表
void display(int* array, int size); // 輸出數(shù)組
int  check(int* array, int size);   // 檢查函數(shù)

/***************************************************************************
 * @date    2020/12/03
 * @brief   合并鏈表
 * @param   head    頭指針
 * @param   list    順序數(shù)據(jù)鏈表
 ***************************************************************************/
BN* merge(BN* head, BN* list)
{
    BN* last   = head;
    last->next = list->next;
    while (last->next) {
        last = last->next;
    }
    return last;
}

/***************************************************************************
 * @date    2020/12/03
 * @brief   順序插入節(jié)點
 * @param   list    代表第幾個桶的鏈表
 * @param   value   數(shù)據(jù)
 ***************************************************************************/
void insert(BN* list, int value)
{
    BN* prev   = list;
    BN* curr   = list->next;
    BN* node   = (BN*)malloc(sizeof(BN));

    node->data = value;
    node->next = NULL;
    if (curr == NULL) {
        prev->next = node;
    } else {
        while (curr != NULL && curr->data < value) {
            prev = curr;
            curr = curr->next;
        }
        prev->next = node;
        node->next = curr;
    }
}

/***************************************************************************
 * @date    2020/12/03
 * @brief   桶排序主程序
 * @param   array   數(shù)組
 * @param   size    數(shù)組大小
 * @param   num     幾個桶
 ***************************************************************************/
void bucket_sort(int* array, int size, int num)
{
    // 申請內(nèi)存,二級指針,初始化,可以理解頭指針沒數(shù)據(jù),從下一個開始存數(shù)數(shù)據(jù)
    BN** buckets = (BN**)malloc(sizeof(BN*) * num);
    for (int i = 0; i < num; i++) {
        *(buckets + i)         = (BN*)malloc(sizeof(BN));
        (*(buckets + i))->next = NULL;
    }

    // 1. 找到最大值和最小值求間隔(桶的大?。?
    int max = array[0];
    int min = array[0];
    for (int i = 0; i < size; i++) {
        if (array[i] > max) {
            max = array[i];
        }
        if (array[i] < min) {
            min = array[i];
        }
    }
    int space = ((max - min) / num) + 1;

    // 2. 一個一個分桶排序
    for (int i = 0; i < size; i++) {
        int n = (array[i] - min) / space;
        insert(*(buckets + n), array[i]);
    }
    for (int i = 0; i < num; i++) {
        printf("第 %d 個桶數(shù)據(jù): ", i);
        displayL((*(buckets + i))->next);
    }

    // // 3. 合并鏈表
    // BN* head   = (BN*)malloc(sizeof(BN));
    // head->next = NULL;
    // BN* last   = merge(head, *(buckets + 0));
    // for (int i = 1; i < num; i++) {
    //     if ((*(buckets + i))->next) {
    //         last = merge(last, *(buckets + i));
    //     }
    // }
    // head = head->next;

    // // 4. 把鏈表值返回數(shù)組
    // for (int i = 0; i < size; i++) {
    //     array[i] = head->data;
    //     head     = head->next;
    // }

    // 3+4. 當(dāng)然也可以不合并鏈表,直接把數(shù)據(jù)返回數(shù)組
    int index = 0;
    for (int i = 0; i < num; i++) {
        if ((*(buckets + i))->next != NULL) {
            BN* temp = (*(buckets + i))->next;
            while (temp != NULL) {
                array[index++] = temp->data;
                temp           = temp->next;
            }
        }
    }
}

int main()
{
    // 測試用例
    // int array[]    = {49, 38, 65, 97, 76, 13, 27, 49, 10};
    // int array_size = sizeof(array) / sizeof(array[0]);
    // int bucket_num = 5;
    // printf("%d \n", array_size);
    // printf("排序前數(shù)組:");
    // display(array, array_size);
    // bucket_sort(array, array_size, bucket_num);
    // printf("排序后數(shù)組:");
    // display(array, array_size);

    // 隨機測試
    int bucket_num = 5;              // 桶的個數(shù)
    int array_num  = 20;             // 數(shù)組數(shù)量
    int array_size = 20;             // 數(shù)組大小
    int array[array_size];           // 數(shù)組初始化
    srand((unsigned int)time(NULL)); // 隨機數(shù)種子,保證每次不一樣
    for (int i = 0; i < array_num; i++) {
        for (int j = 0; j < array_size; j++) {
            array[j] = rand() % 1000; // 隨機生成數(shù)大小 0~999
        }
        printf("原來的數(shù)組:");
        display(array, array_size);
        bucket_sort(array, array_size, bucket_num);
        printf("排序后數(shù)組:");
        display(array, array_size);
        // 檢測排序結(jié)果
        if (check(array, array_size) != 0) {
            exit(-1);
        }
        printf("\n");
    }

    return 0;
}

/***************************************************************************
 * @date    2020/12/03
 * @brief   輸出線性表
 * @param   L   首節(jié)點
 ***************************************************************************/
void displayL(BN* L)
{
    BN* p = L;                  // p 指向首結(jié)點
    while (p != NULL) {         // 不為空,依次遍歷
        printf("%d ", p->data); // 打印
        p = p->next;            // p 移向下一個節(jié)點
    }
    printf("\n");
}

/***************************************************************************
 * @date    2020/12/03
 * @brief   輸出數(shù)組
 * @param   array   數(shù)組
 * @param   size    數(shù)組大小
 ***************************************************************************/
void display(int* array, int size)
{
    for (int i = 0; i < size; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");
}

/**
 * @brief 檢查函數(shù),從小到大
 *
 * @param array        數(shù)組首指針
 * @param size         數(shù)組大小
 */
int check(int* array, int size)
{
    for (int i = 0; i < size - 1; i++) {
        if (array[i] > array[i + 1]) {
            printf("sort array fail...\n");
            return -1;
        }
    }
    printf("sort array success...\n");
    return 0;
}

5. 結(jié)果展示

在這里插入圖片描述

6. 算法分析

時間復(fù)雜度:

  • 最好: O ( n ) O(n) O(n)
  • 最壞: O ( n 2 ) O(n^{2}) O(n2)
  • 平均: O ( n + k ) O(n+k) O(n+k)

空間復(fù)雜度: O ( n ∗ k ) O(n*k) O(n∗k)

穩(wěn)定性:穩(wěn)定(也有說根據(jù)桶內(nèi)排序決定穩(wěn)定性)

到此這篇關(guān)于C語言排序算法之桶排序解析的文章就介紹到這了,更多相關(guān)C語言桶排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實現(xiàn)的求解多元一次方程示例

    C++實現(xiàn)的求解多元一次方程示例

    這篇文章主要介紹了C++實現(xiàn)的求解多元一次方程,涉及C++矩陣運算相關(guān)操作技巧,需要的朋友可以參考下
    2018-01-01
  • C語言中的pause()函數(shù)和alarm()函數(shù)以及sleep()函數(shù)

    C語言中的pause()函數(shù)和alarm()函數(shù)以及sleep()函數(shù)

    這篇文章主要介紹了C語言中的pause()函數(shù)和alarm()函數(shù)以及sleep()函數(shù),是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • VScode中添加頭文件和源文件(C/C++)的方法

    VScode中添加頭文件和源文件(C/C++)的方法

    使用VSCode編譯C/C++時,會存在找不到頭文件的情況,下面這篇文章主要給大家介紹了關(guān)于VScode中添加頭文件和源文件(C/C++)的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • C++中的頭文件與Extern(外部函數(shù)調(diào)用)方式

    C++中的頭文件與Extern(外部函數(shù)調(diào)用)方式

    這篇文章主要介紹了C++中的頭文件與Extern(外部函數(shù)調(diào)用)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C語言修煉之路初識指針陰陽竅?地址還歸大道真上篇

    C語言修煉之路初識指針陰陽竅?地址還歸大道真上篇

    指針是指向另一個變量的變量。意思是一個指針保存的是另一個變量的內(nèi)存地址。換句話說,指針保存的并不是普通意義上的數(shù)值,而是另一個變量的地址值。一個指針保存了另一個變量的地址值,就說這個指針“指向”了那個變量
    2022-02-02
  • C++實現(xiàn)LeetCode(31.下一個排列)

    C++實現(xiàn)LeetCode(31.下一個排列)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(31.下一個排列),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 深入HRESULT與Windows Error Codes的區(qū)別詳解

    深入HRESULT與Windows Error Codes的區(qū)別詳解

    本篇文章是對HRESULT與Windows Error Codes的區(qū)別進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C語言實現(xiàn)變色進度條

    C語言實現(xiàn)變色進度條

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)一個變色的進度條,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • Linux系統(tǒng)下C語言中的標(biāo)準(zhǔn)IO總結(jié)

    Linux系統(tǒng)下C語言中的標(biāo)準(zhǔn)IO總結(jié)

    最近用到了C語言的標(biāo)準(zhǔn)IO庫,由于對其中的一些細節(jié)不是非常清楚,導(dǎo)致了許多Bug,花了好長時間來調(diào)試,所以在此做個筆記,這篇文章主要給大家介紹了關(guān)于Linux系統(tǒng)下C語言中標(biāo)準(zhǔn)IO的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • C++超詳細分析函數(shù)重載的使用

    C++超詳細分析函數(shù)重載的使用

    C++?允許多個函數(shù)擁有相同的名字,只要它們的參數(shù)列表不同就可以,這就是函數(shù)的重載(Function?Overloading),借助重載,一個函數(shù)名可以有多種用途
    2022-04-04

最新評論