정렬 알고리즘 리니어 (선형 시간 복잡도)

버킷 정렬

  • 핵심 아이디어는 아래 몇 가지 주문 양동이, 행 또는 빠른 거품 정렬 알고리즘 등을 기준으로 정렬 데이터에 혼자 다음 각 버킷과로 데이터를 정렬하는 일종의 버킷입니다. 빈 정렬이 완료되면,이어서 순차적 버킷의 시퀀스로 구성되고, 데이터의 순서로 순차적으로 추출 하였다.
  • 버킷 정렬 시간 복잡도는 O (n)이된다. N, 우리는 각 버킷 K = N / m의 요소가 균등 m 버킷 나누어 넣어 한 데이터 정렬 될 경우, 우리는 분석. 빠른 정렬을 사용하여 욕조의 각각의 내부는, 시간 복잡도는 O (K * logk)입니다. m 배럴 복잡도가 O (m * K * logk)는 시간 정렬 된 K = N / m 때문에, 그래서 전체 버킷 정렬 시간 복잡도는 O임을 (N * 로그 (N / m)). 데이터의 수 (N), 로그 (N / m)에 근접 터브의 개수 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;
}

계수 정렬

  • 해당 데이터가 크지되는 범위, 정렬 될 때 최대가 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