ソート線形アルゴリズム(線形時間複雑)

バケットソート

  • 核となるアイデアは、ダウンいくつかの順序付けられたバケット、行または高速バブルソートアルゴリズム等によってソートデータに単独で、各バケットにデータをソートするソートバケットにあります。ビンをソートが完了した後、バケットを次いで整然としたのシーケンスで構成され、データの順で順次抽出しました。
  • バケットソート時間複雑度はO(N)です。nは、我々は、各バケットは、K = N / m個の要素を持って均等にm個のバケットに分割して入れているデータをソートする場合我々は、分析します。クイックソートを使用してタブの各内部は、時間の複雑さはO(K * logk)です。Mバレルは、複雑さはO(M * K * logk)であり、全体バケットソートの時間計算量はO(N *ログ(N / M))であるように、K = N / Mのための時間を命じました。数値データの数にタブ近くのM nは、ログは(N / M)は非常に小さい定数である場合、時間計算際にバケットソート近接O(N)。
  • しかし、バケットは、ソート非常に厳しいのデータ要件をソートします。まず、データを容易にm個のバケットに分割することができるソートする必要があり、タブとタブとの間の大きさの自然な順序があります。このようなデータは、完全な樽ごとにソートされた後、浴槽と浴槽の間でデータをソートする必要はありません。第二に、各バケットとの間のデータの分布が比較的均一です。バケット分割後のデータ、バケット及びデータの一部が非常に大きい場合、いくつかの非常に小さいが、非常に平均、バケットデータをソートの時間計算量は一定ではありません。データは、ソートアルゴリズムのO(nlogn)に還元、バケットに分割され、極端な場合には、場合。
  • バケットソート外部ソートでの使用に適しています。外部ディスクでは、データは、いわゆる外部ソートよりも大きいことは、データストレージ、限られたメモリであり、すべてのデータがメモリにロードすることができません。
  • もちろん、データの缶胴再び小さいバケットに分割されます。

アルゴリズム:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int _tmain(int argc, _TCHAR* argv[]){
	int array_stu[50]={0};
	int array_out[100]={0};
    
    srand((int)time(NULL));//设置随机数的基准,这样保证每次的运行结果不同

    for(int i=0;i<50;i++)
    {
        array_stu[i] =(rand()%(99-1))+1;
    }

    /*把array_stu分别扔到对应的桶里面去
    里面的逻辑需要根据要求进行修改,这里是如果数值跟桶的编号一样,就把这个桶的数据增加
    */
    for(int i=0;i<50;i++)
    {
        for(int j=1;j<100;j++)
        {
            /*如果数值跟桶的编号一样,就把这个桶的数据增加*/
            if(array_stu[i] ==j)
            {
                array_out[j] ++;
            }
        }
    }
    
    /*把排序后的数据输出*/
    for(int i=0;i<100;i++)
    {
        while(array_out[i] > 0)
        {
            printf("%d\n",i);
            array_out[i]--;
        }
    }
	return 0;
}

カウンティングソート

  • N個のデータが大きいされていない範囲で、ソートする際に、最大Kであるような、我々は、k個のバケットにデータを置くことができます。データ値は、各バレルのために同じである、バレルは時間をソート省略する。
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
//计数排序
void CountSort(int *a, int len)
{
	//通过max和min计算出临时数组所需要开辟的空间大小
	int max = a[0], min = a[0];
	for (int i = 0; i < len; i++){
		if (a[i] > max)
			max = a[i];
		//if (a[i] < min)
		//	min = a[i];
	}
	//使用calloc将数组都初始化为0
//	int range = max - min + 1;
	int *b = (int *)calloc(max, sizeof(int));
	//使用临时数组记录原始数组中每个数的个数
	for (int i = 0; i < len; i++){
		//注意:这里在存储上要在原始数组数值上减去min才不会出现越界问题
		b[a[i]] += 1;
	}
	int j = 0;
	//根据统计结果,重新对元素进行回收
	for (int i = 0; i < max; i++){
		while (b[i]){
			//注意:要将i的值加上min才能还原到原始数据
			a[j++] = i ;
			b[i]--;
		}
	}
}
//打印数组
void PrintArray(int *a, int len)
{
	for (int i = 0; i < len; i++){
		printf("%d ", a[i]);
	}
	printf("\n");
}

int _tmain(int argc, _TCHAR* argv[]){
	int a[] = { 3, 4, 3, 2, 1, 2, 6, 5, 4, 7 };
	printf("排序前:");
	PrintArray(a, sizeof(a) / sizeof(int));
	CountSort(a, sizeof(a) / sizeof(int));
	printf("排序后:");
	PrintArray(a, sizeof(a) / sizeof(int));
	system("pause");
	return 0;
}
公開された60元の記事 ウォンの賞賛0 ビュー839

おすすめ

転載: blog.csdn.net/qq_36828822/article/details/104063691