zoukankan      html  css  js  c++  java
  • 《算法导论》笔记·第八章 线性时间排序/计数排序、基数排序和桶排序

    #---2020.5.3
    #---第八章·线性时间排序
    

      

    计数排序

    /*
     *	计数排序
     *	时间复杂度为O(n+k)
     *	使用计数排序须要在全部元素都在一个小的范围内,即k远小于n
     *	在k=O(n)时。时间复杂度为O(n)
     */
    

      

    // COUNTING-SORT
    int* countingSort(int *arr, int len, int k)
    {
    	int *numCount = new int[k]();
    	int *result = new int[len];
    	
    	// now C[i] contains the number of elements equal to i
    	for (int i=0; i<len; i++)
    	{
    		numCount[arr[i]]++;
    	}
     
    	// now C[i] contains the number of elements less than or equal to i
    	for (int i=1; i<k; i++)
    	{
    		numCount[i] += numCount[i-1];
    	}
     
    	for (int i=len-1; i>=0; i--)
    	{
    		result[numCount[arr[i]]-1] = arr[i];
    		numCount[arr[i]]--;
    	}
     
    	delete[] numCount;
    	return result;
    }
    

      

    基数排序

    /*
     *	基数排序
     *	是建立在计数排序的基础之上的,计数排序的稳定性非常重要
     *	否则基数排序就会出错,比如数组[27, 15, 43, 42],假设子排序过程不稳定
     *	则结果就为[15, 27, 43, 42]
     *	时间复杂度为O(d*(n+k)),在d为常数,k=O(n)时,时间复杂度为O(n)
     */
    

      

    // RADIX-SORT
    int* radixSort(int *arr, int len, int d)
    {
    	int *A = new int[len];
    	for (int i=0; i<len; i++)
    		A[i] = arr[i];
    	for (int j=0; j<d; j++)
    	{
    		int k = 10;
    		int *numCount = new int[k]();
    		int *result = new int[len];
     
    		//numCount中存储等于i的元素个数
    		for (int i=0; i<len; i++)
    		{
    			numCount[getDigit(A[i], j)]++;
    		}
     
    		//numCount中存储小于等于i的元素个数
    		for (int i=1; i<k; i++)
    		{
    			numCount[i] += numCount[i-1];
    		}
     
    		//从后至前依次对元素进行排序。保证稳定性,也能够从前往后,可是排序就不稳定了
    		for (int i=len-1; i>=0; i--)
    		{
    			result[numCount[getDigit(A[i], j)]-1] = A[i];
    			numCount[getDigit(A[i], j)]--;
    		}
    		delete[] A;
    		delete[] numCount;
    		A = result;
    	}
    	return A;
    }
    int getDigit(int num, int d)
    {
    	return (num % (int)pow(10.0, d+1)) / pow(10.0, d);
    }
    

      

    桶排序

    /*
     *	桶排序
     *	在输入符合均匀分布时,桶排序的效果较好
     *	将各个元素分布在n个桶中。每一个桶内再使用插入排序
     *	仅仅要各个桶的尺寸的平方和与总的元素数呈线性关系
     *	则其时间复杂度就为O(n)
     */
    

      

    // BUCKET-SORT
    int* bucketSort(int *arr, int len, int maxNum)
    {
    	//建立n个桶
    	vector<int> *result = new vector<int>[len];
    	//将各个元素分布到各个桶内
    	for (int i=0; i<len; i++)
    	{
    		result[(int)((arr[i]/(double)maxNum)*len)].push_back(arr[i]);
    	}
     
    	for (int i=0; i<len; i++)
    	{
    		int n = result[i].size();
    		//插入排序
    		for (int j=1; j<n; j++)
    		{
    			int k = j - 1;
    			int key = result[i][j];
    			while (k>=0 && result[i][k]>key)
    			{
    				result[i][k+1] = result[i][k];
    				k--;
    			}
    			result[i][k+1] = key;
    		}
    	}
    	//合并各个桶中的元素
    	for (int i=0, j=0; j<len; j++)
    	{
    		int length = result[j].size();
    		for (int k=0; k<length; k++)
    		{
    			arr[i++] = result[j][k];
    		}
    	}
     
    	delete[] result;
    	return arr;
    }
    

      

  • 相关阅读:
    实验4:开源控制器实践——OpenDaylight
    实验3:OpenFlow协议分析实践
    实验2:Open vSwitch虚拟交换机实践
    第一次个人编程作业
    SDN实验1:SDN拓扑实践
    第一次博客作业
    LeetCode-1290.Convert Binary Number in a Linked List to Integer
    面试题 02.02. Kth Node From End of List LCCI
    剑指 Offer 24. 反转链表
    剑指 Offer 06. 从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/jaszzz/p/12821132.html
Copyright © 2011-2022 走看看