最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言中如何實現(xiàn)桶排序

 更新時間:2022年11月11日 14:32:42   作者:NPC的克星  
這篇文章主要介紹了C語言中如何實現(xiàn)桶排序問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

C語言實現(xiàn)桶排序

1.原理

由映射函數(shù)分配初始元素的鍵值,然后將這些元素放入對應鍵值的桶中,并對桶中的數(shù)據(jù)進行排序。然后依次將每個桶中的元素分出得到排好序的序列。

在這里插入圖片描述

2.桶排序不是基于比較的排序

將N個待排序的元素放入桶中只需要O(n)時間。后續(xù)則是對桶中元素的排序,所以當桶越多的時候,桶中的元素會越少,所采取的基于比較的排序算法的時間則會大大減少。

所以,這里我們就可確定了一個重點,即是桶的數(shù)量必須是有限個的,可以經(jīng)過一系列運算得到具體數(shù)目的。

3.桶的實現(xiàn)形式

我們以結(jié)構(gòu)體數(shù)組存儲單鏈表實現(xiàn)。以結(jié)構(gòu)體數(shù)組的數(shù)組單元來春初鏈表的頭節(jié)點,頭節(jié)點含有兩個變量,為指針變量(指向下一個鏈表節(jié)點),和整形變量key(就是如下圖里面頭節(jié)點的值),key表示鏈表的節(jié)點個數(shù)。

在這里插入圖片描述

4.桶中元素的排序

因為桶是采取單鏈表來實現(xiàn)的,所以桶中元素的插入就是鏈表中的元素插入。這里要注意分桶為空和非空兩種情況來插入。

	if(p->key == 0){
			bucket_table[index]->next = node_branch;
			(bucket_table[index]->key)++;
		} 
		//鏈表的插入形式,按照大小從后到大。 
		else{
			while(p->next!=NULL && p->next->key <= node_branch->key){
			p=p->next;				
			}	
			node_branch->next = p->next;
			p->next = node_branch;
			(bucket_table[j]->key)++;
		}

4.最后就是將桶中的元素依次輸出

或存放到數(shù)組原始序列的數(shù)組中。

5完整代碼如下

#include<stdio.h>
#include<stdlib.h>
//整體思想大致為用數(shù)組單元內(nèi)存放的為結(jié)構(gòu)體式的鏈表,每個鏈表稱為一個桶。通里面容納的都是鍵值相同的元素。 
// 之后便是查看對應元素的鍵值,然后放進與之對應的桶,還需注意桶為空和不空的時的放入方式
//桶元素的插入就是看桶以什么方式的實現(xiàn)。這里桶以鏈表的形式表現(xiàn),所以桶中元素的插入即為鏈表中數(shù)組的插入。
/*只要桶的數(shù)量夠多,那么之前的放入操作只需花費O(n)的時間,而后面的對每個桶里面的元素進行排序則需要基于比較的排序算法。因此后面算法的選擇也是
關(guān)乎桶排序速度的重要因素。 
 */ 
//桶排序的特點是要有界限分明的桶,而不能是無限個桶,也就是說桶排序的個數(shù)應該是可以確定的,有限個的。 
//這里鏈表實現(xiàn)桶排序的還有要注意的點,就是數(shù)組的首地址其實鏈表的頭節(jié)點,有這里的值確定該桶的元素個數(shù),并由這里出發(fā)尋找其他元素。 
typedef struct node *Snode;
typedef struct node{
	int key;
	Snode next;
}BBc;

void sort(int keys[],int keys_size,int bucket_size)
{
	Snode *bucket_table = (Snode *)malloc(bucket_size*sizeof(Snode));//為結(jié)構(gòu)體數(shù)組分配空間。 
	for(int i=0;i<bucket_size;i++)//對每個數(shù)組單元賦予內(nèi)存空間時,初始化每個結(jié)構(gòu)體數(shù)組單元。 
	{
		bucket_table[i] = (Snode)malloc(sizeof(Snode));//這一步是必要的,因為之前只是給數(shù)組分配了一連串的存儲空間,但是每個單元的存儲地址都是 
	    //不確定,也不確定該方式是否會自動地分配內(nèi)存空間給每個數(shù)組單元。 
	    //那么這樣準確的給數(shù)組單眼分配的空間是占用之前的分配給數(shù)組的空間,還是重新分撥其他的空間給數(shù)組單元。
		//其實應該是分配之前給整個數(shù)組單元分配的一段存儲空間。 
		bucket_table[i]->key = 0;
		bucket_table[i]->next = NULL;
	}//其實創(chuàng)建數(shù)組這部分應該放在主函數(shù)那里,否則某些功能只能在這個函數(shù)中使用。 
	for(int j=0;j<keys_size;j++)
	{
		Snode node_branch = (Snode)malloc(sizeof(Snode));//定義一個節(jié)點,滿足條件時鏈入以鏈表為表現(xiàn)形式的桶。 
		node_branch->key = keys[j];
		node_branch->next = NULL;
		int index = keys[j]/10;
		Snode p = bucket_table[index];//p用來充當指向循環(huán)的變量。 
		//桶為空和非空時的兩種插入形式 
		if(p->key == 0){
			bucket_table[index]->next = node_branch;
			(bucket_table[index]->key)++;
		} 
		//鏈表的插入形式,按照大小從后到大。 
		else{
			while(p->next!=NULL && p->next->key <= node_branch->key){
			p=p->next;				
			}	
			node_branch->next = p->next;
			p->next = node_branch;
			(bucket_table[j]->key)++;
		}
	}
	//以此輸出每個桶中的所有元素。 
	for(int i=0;i<bucket_size;i++){
		for(Snode k = bucket_table[i]->next;k!=NULL;k = k->next){
			printf(" %d ",k->key);
		}
	}
	
}

int main()
{
	int keys[] = {49,26,53,47,89,31,72,11,33};
	int keys_size = sizeof(keys)/sizeof(int);
	int bucket_size = keys_size+2;
	sort(keys,keys_size,bucket_size);
}

7.桶排序的時間復雜度和空間復雜度

前面的將n個待排序元素分到對應鍵值的桶中只需要O(n)時間,后面則是基于比較的排序算法,基于比較的排序算法最快可以達到:O(nlogn)時間。

所以桶里面的排序算法的選擇也會影響到桶排序的速度。至于空間復雜度,一般都是占用空間比較大,以便每個桶中盡可能的達到一個元素,這樣桶里面的排序也是O(n)時間,可以說是非??焖俚?。所以桶排序也是一種空間換時間的排序。 

另外桶排序的元素鍵值應該相差不大,以免照成空間的浪費。另外,劃分的桶也應該是有限個的。

【排序】圖解桶排序

思想

一句話總結(jié):劃分多個范圍相同的區(qū)間,每個子區(qū)間自排序,最后合并。

桶排序是計數(shù)排序的擴展版本,計數(shù)排序可以看成每個桶只存儲相同元素,而桶排序每個桶存儲一定范圍的元素,通過映射函數(shù),將待排序數(shù)組中的元素映射到各個對應的桶中,對每個桶中的元素進行排序,最后將非空桶中的元素逐個放入原序列中。

桶排序需要盡量保證元素分散均勻,否則當所有數(shù)據(jù)集中在同一個桶中時,桶排序失效。

圖解過程

核心代碼

public static void bucketSort(int[] arr){
    
    // 計算最大值與最小值
    int max = Integer.MIN_VALUE;
    int min = Integer.MAX_VALUE;
    for(int i = 0; i < arr.length; i++){
        max = Math.max(max, arr[i]);
        min = Math.min(min, arr[i]);
    }
    
    // 計算桶的數(shù)量
    int bucketNum = (max - min) / arr.length + 1;
    ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
    for(int i = 0; i < bucketNum; i++){
        bucketArr.add(new ArrayList<Integer>());
    }
    
    // 將每個元素放入桶
    for(int i = 0; i < arr.length; i++){
        int num = (arr[i] - min) / (arr.length);
        bucketArr.get(num).add(arr[i]);
    }
    
    // 對每個桶進行排序
    for(int i = 0; i < bucketArr.size(); i++){
        Collections.sort(bucketArr.get(i));
    }
    
    // 將桶中的元素賦值到原序列
	int index = 0;
	for(int i = 0; i < bucketArr.size(); i++){
		for(int j = 0; j < bucketArr.get(i).size(); j++){
			arr[index++] = bucketArr.get(i).get(j);
		}
	}  
}

復雜度分析

1. 時間復雜度:O(N + C)

對于待排序序列大小為 N,共分為 M 個桶,主要步驟有:

  • N 次循環(huán),將每個元素裝入對應的桶中
  • M 次循環(huán),對每個桶中的數(shù)據(jù)進行排序(平均每個桶有 N/M 個元素)

一般使用較為快速的排序算法,時間復雜度為O(NlogN),實際的桶排序過程是以鏈表形式插入的。

整個桶排序的時間復雜度為:

O(N)+O(M*(N/M*log(N/M)))=O(N*(log(N/M)+1))

當 N = M 時,復雜度為 O(N)

2. 額外空間復雜度:O(N + M)

穩(wěn)定性分析

桶排序的穩(wěn)定性取決于桶內(nèi)排序使用的算法。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C語言代碼實現(xiàn)簡單的掃雷小游戲

    C語言代碼實現(xiàn)簡單的掃雷小游戲

    這篇文章主要為大家詳細介紹了C語言代碼實現(xiàn)簡單的掃雷小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • 代碼分析c++中string類

    代碼分析c++中string類

    本篇內(nèi)容通過詳細的源代碼詳細分析了C++中string類的用法以及知識點,有興趣的讀者們參考下。
    2018-03-03
  • C語言字符串另類用法的實現(xiàn)

    C語言字符串另類用法的實現(xiàn)

    今天小編就為大家分享一篇關(guān)于C語言字符串另類用法的實現(xiàn),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • C++實現(xiàn)DES加密算法實例解析

    C++實現(xiàn)DES加密算法實例解析

    這篇文章主要介紹了C++實現(xiàn)DES加密算法實例解析,是一個很實用的功能,需要的朋友可以參考下
    2014-08-08
  • C語言常見的文件操作函數(shù)

    C語言常見的文件操作函數(shù)

    這篇文章主要為大家介紹了C語言文件操作函數(shù),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • c++ 端口掃描程序?qū)崿F(xiàn)案例

    c++ 端口掃描程序?qū)崿F(xiàn)案例

    下面小編就為大家?guī)硪黄猚++ 端口掃描程序?qū)崿F(xiàn)案例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • C++ 如何判斷四個點是否構(gòu)成正方形

    C++ 如何判斷四個點是否構(gòu)成正方形

    這篇文章主要介紹了C++ 如何判斷四個點是否構(gòu)成正方形的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • 賭你會懵的C語言指針進階數(shù)組場景解析

    賭你會懵的C語言指針進階數(shù)組場景解析

    這篇文章主要為大家介紹了關(guān)于C語言指針進階的示例解析,來細化指針這一部分內(nèi)容,現(xiàn)在著重把一些指針的運用情景搬出來康康,如果對指針盤的不是非常熟練,或者指針還出于入門階段的鐵子請繞道
    2022-02-02
  • C語言之二叉樹的遍歷

    C語言之二叉樹的遍歷

    這篇文章主要介紹了C語言中二叉樹的遍歷:前序、中序、后序,認識二叉樹結(jié)構(gòu)最簡單的方式就是遍歷二叉樹,感興趣的小伙伴可以參考閱讀本文
    2023-03-03
  • Visual Studio 2019配置qt開發(fā)環(huán)境的搭建過程

    Visual Studio 2019配置qt開發(fā)環(huán)境的搭建過程

    這篇文章主要介紹了Visual Studio 2019配置qt開發(fā)環(huán)境的搭建過程,本文圖文并茂給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03

最新評論

施秉县| 桂阳县| 萨迦县| 花莲市| 武城县| 雷波县| 林芝县| 竹北市| 德庆县| 盱眙县| 江口县| 乌恰县| 烟台市| 繁昌县| 丽水市| 明光市| 庆元县| 青浦区| 朝阳市| 乌拉特后旗| 文安县| 静海县| 牡丹江市| 黎川县| 五台县| 涞水县| 壶关县| 环江| 靖宇县| 鄯善县| 辽阳市| 满城县| 百色市| 饶平县| 永定县| 东丽区| 新竹县| 鱼台县| 呼伦贝尔市| 泾阳县| 临汾市|