基数排序算法分析

基数排序:主要思想是把数字按位进行比较,从个位,十位... 到最高位,取得每个位的单个数字逐一进行比较和移动。

由于整数也可以用字符串表达(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数,其他类型也可使用这种方式。


#include <stdio.h>

typedef struct _node
{
    int m_value;
    int m_base;
} node;

int process_data(node* pList, int len, int weight)
{
    int nValue = 1;
    int i=0;
    int nFlag = 0;
 
    // weight is start from 1 
    for (i=0; i< weight; i++)
    {
         nValue *= 10;
    }

    for (i=0; i < len; i++)
    {
        if (weight == 1)
        {
            (pList+i)->m_base = (pList+i)->m_value % nValue;
            nFlag = 1;
        }
        else
        {
            // 此处主要用于处理负数情况
            if ((pList+i)->m_value >= 0)
                (pList+i)->m_base = -10;
            else
                (pList+i)->m_base = -11;

            // 每次提取数字中的位数是在10的n次方和(n-1)次方之间
            if ((((pList+i)->m_value < 0)&&((pList+i)->m_value*(-1) > (nValue/10)))
               || (((pList+i)->m_value > 0) && ((pList+i)->m_value > (nValue/10))))
            {
                (pList+i)->m_base = ((pList+i)->m_value%nValue)/(nValue/10);
                nFlag = 1;
            }
        }
    }

    return nFlag;
}


void base_sort(int arr[], int len)
{ 
    int i = 0;
    int j = 0;
    int nCnt = 0;
    int nWeight = 1;
    node* pData = (node*)malloc(len*sizeof(node)); 
    node* pTmpList = (node*)malloc(len*sizeof(node));

    for (i = 0; i < len; i++)
    {
        (pData+i)->m_value = arr[i];
        (pData+i)->m_base  = -10;
    }

    while(process_data(pData, len, nWeight))
    {
         nCnt = 0;
         nWeight++;
         for (j = -11; j < 10; j++)
         {
             for (i=0; i < len; i++)
             {
                 if ((pData+i)->m_base == j)
                 {
                     (pTmpList+nCnt)->m_value = (pData+i)->m_value;
                     nCnt++;
                 }
             }
         }
         memcpy(pData, pTmpList, sizeof(node)*len);
    }

    // finished the sort, re-copy the result
    for (i=0; i < len; i++)
    {
        arr[i] = (pData+i)->m_value;
    }

    free(pData);
    free(pTmpList);
}

int main()
{
    int test1[] = {3, 90, -20, 156, 839, 98, 643,1,900, 66};
    int i = 0;

    for (i=0; i < 10; i++)
    {
        printf("%d ", test1[i]);
    }
    printf("\n\n");


    base_sort(test1, 10);

    for (i=0; i < 10; i++)
    {
        printf("%d ", test1[i]);
    }
    printf("\n\n");

    scanf("%d", &i);
    return 0; 
}


基数排序的时间复杂度是 O(k·n),其中n是排序元素个数,k是数字位数。


再贴一段:

#include <iostream>

using namespace std;

int preprocess(int arr[], int nLen, int nWeight)
{
    int i = 0;
    int value = 1;
    int nRet = 0;

    for (i = 0; i < nWeight; i++)
        value *= 10;


    for (i = 0; i < nLen; i++)
    {
         arr[i] = arr[i] % value / (value / 10);
         if (arr[i] > 0)
             nRet = 1;
    }

    for (i = 0; i < nLen; i++)
    {
         cout << arr[i] << "   ";
    }

	cout << endl;

    return nRet;
}


void sortsignalpos(int arr[], int nLen)
{
    int i = 0, j = 0;
    int val = 0;
    int *tmparr = (int*) malloc(sizeof(int) * nLen);

    memset(tmparr, 0, sizeof(int)*nLen);

    for (val = -9; val < 10; val++)
    {
        for(i = 0; i < nLen; i++)
        {
            if ((arr[i] != -10) && (arr[i] == val))
            {
                tmparr[j] = arr[i];
                j++;
                arr[i] = -10;
            }
        }
    }

    for (i=0; i < nLen ; i++)  
    {  
        cout << tmparr[i] << "  ";  
    }
	cout << endl;

    memcpy(arr, tmparr, nLen*sizeof(int));

    free(tmparr);
}

void basesort(int arr[], int nLen)
{
    int i = 0, j = 0, k = 0;
    int weight = 1;
    int value = 1;
    int *tmparr = (int*) malloc(sizeof(int) * nLen);
    int *swaparr = (int*) malloc(sizeof(int) * nLen);

    memcpy(tmparr, arr, nLen*sizeof(int));
    memset(swaparr, 0, sizeof(int)*nLen);

    while(true)
    {
        if (preprocess(tmparr, nLen, weight) == 0)
            break;

        value = 1;
        for (i = 0; i < weight ; i++)
            value *= 10;

        sortsignalpos(tmparr, nLen);

		k = 0;
        for (i = 0; i < nLen; i++)
        {
            for (j = 0; j < nLen; j++)
            {
                if ((arr[j] != 0xffff) && ((tmparr[i] != -10) && (tmparr[i] == (arr[j] % value /(value / 10)) )))
                {
                    swaparr[k] = arr[j];
                    tmparr[i] = -10;
                    k++;
					arr[j] = 0xFFFF;
                }
            }
        }

        memcpy(arr, swaparr, nLen*sizeof(int));
        memcpy(tmparr, swaparr, nLen*sizeof(int));
        for (i=0; i < nLen ; i++)  
        {  
            cout << tmparr[i] << "  ";  
        }
        cout << endl;
		weight++;
    }

    memcpy(arr, swaparr, nLen*sizeof(int));

    free(tmparr);
    free(swaparr);
    tmparr = NULL;
    swaparr = NULL;
}

int main()
{
    int i = 0;
    int test1[] = {3, 90, -20, 156, 839, 98, 643,1,900, 66};  
    int nLen = 10;  
  
    for (i=0; i < nLen ; i++)  
    {  
        cout << test1[i] << "  ";  
    }  
    cout << endl; 
  
    basesort(test1, nLen);  
  
    for (i=0; i < nLen ; i++)  
    {  
        cout << test1[i] << "  ";  
    }  
    cout << endl;   

    cin >> i;
    return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值