基数排序-数组模拟实现

之前用队列实现了基数排序,后来我想了想,结合桶排的思路,计数排序的思路,我觉得根本不需要队列,用队列太麻烦了,结合别人的代码部分,加上自己的理解,在这里讲解一下:数组是如何模拟基数排序的分配和收集过程的?
#include<stdio.h>
#include<malloc.h>
int getdigit(int x,int d)   //取每个数的各个位上的数字
{
	while(--d)
	{
		x/=10;
	}
    return x%10;
}  

void Print_Array(int a[],int n)    //打印操作
{
	int i;
    for(i=0;i<n;++i)
        printf("%d ",a[i]);
    printf("\n");
}

int Maxdigit(int a[],int n)           //获取待排序列中位数最多为多少,用以确定分配收集的次数
{
	int i,max=-1,flag;
	for(i=0;i<n;i++)
	{
		int temp=a[i];
		flag=0;
		while(temp)
		{
			flag++;
			temp/=10;
		}
		if(flag>max)
			max=flag;
	}
	return max;
}

void LSD_radix_sort(int arr[],int begin,int end,int d)   //LSD(从最低位开始分配收集)
{
    const int radix=10;
    int count[radix],i,j;
    int *bucket=(int*)malloc((end-begin+1)*sizeof(int));  //所有桶的空间开辟
    for(int k=1;k<=d;++k)     //总共d次分配操作                //按照分配标准依次进行排序过程
    {
        for(i=0;i<radix;i++)           //置空(初始化操作)---为位数不够的数进行补0操作
            count[i]=0;              <span style="font-family: Arial, Helvetica, sans-serif;">//统计各个桶中所盛数据个数</span>

        for(i=begin;i<=end;i++)
        {                              <span style="font-family: Arial, Helvetica, sans-serif;">//统计每次分配后各个桶所需要的存储空间大小</span>
           count[getdigit(arr[i],k)]++;
        }
                                             //count[i]表示第i个桶的右边界索引(即存放的极限下标)
        for(i=1;i<radix;i++)
        {                                          //这样第count[i]就表示前i个桶所存有的数据个数值(也就是个数)
            count[i]=count[i]+count[i-1];               //count[i]表示收集每个桶后bucket[]所存有的上边界
        }                                     <span style="font-family: Arial, Helvetica, sans-serif;">//把数据依次装入桶(注意装入时候的分配技巧)</span><span style="font-family: Arial, Helvetica, sans-serif;">       </span>
        for(i=end;i>=begin;--i)                    //这里要从右向左扫描,确保是先进先出(先入桶的先出来)
        {
            j=getdigit(arr[i],k);                        //求出关键字的第k位的数字, 例如:675的第3位是6
            bucket[count[j]-1]=arr[i];   //放入对应的桶中(说是放入桶,实则是收集过程,两个过程合而为一了),count[j]-1就是这个数在bucket[]中应该存放的位置
            --count[j];                            //收集好一个数后,相应桶中的个数就要减一
        }                                     //这整个循环的目的是将各个桶中的分配数据进行收集(但要避免被覆盖,所以出现了上述的代码)
/*
举个例子说明一下:  假设你5号桶中分配的数据个数为3个,3次都是count[5],根据我们上一层循环count[i]的含义就知道,这样每次的count[j]-1都是不一样的,这样就不会被覆盖了,你要是不懂,我也没办法 */
        for(i=begin,j=0;i<=end;++i,++j)
        {
            arr[i]=bucket[j];     //从各个桶中收集数据(收集过程)
        }
    }
    free(bucket);
}  

int main()
{
    int a[10000],n,i;
	printf("请输入待排序列的个数\n");
	scanf("%d",&n);
	printf("请输入待排的序列:\n");
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);
    int digits=Maxdigit(a,n);
    LSD_radix_sort(a,0,n-1,digits);
    printf("基数排序结果如下:\n");
    Print_Array(a,n);
	return 0;
}
知道了LSD是这样子的,那么你能弄出MSD是怎样的代码吗?自己动手试<span style="font-family: Arial, Helvetica, sans-serif;">试,真正理解了就很简单哦~</span>

时间: 2024-08-09 21:43:17

基数排序-数组模拟实现的相关文章

队列(数组模拟)

//队列(数组模拟) class Queue{ private int[] queue; //队列函数 int length; int head; //头指针 int tail; //尾指针 int num; //丢列中元素个数 public Queue(){ } public Queue(int s){ //构造队列函数 length=s; queue=new int[length]; //s为队列长度 head=0; tail=-1; num=0; } public void inQueue

数组模拟单向链表例题(UVa11988)

指针的链表实现方式是,当前节点的next指向下一个节点,用数组模拟就是 for(int i=next[0];i!=0;i=next[i]) i=next[i]:就是一条链. 例题: 你有一个破损的键盘.键盘上的所有键都可以正常工作,但有时Home键或者End键会自动按下.你并不知道键盘存在这一问题,而是专心打稿子,甚至连显示器都没打开.当你打开显示器时之后,展现在你面前的是一段悲剧文本.你的任务时在打开显示器之前计算出这段悲剧文本. 输入包含多组数据.每组数据占一行,包含不超过100000个字母

UVA11988 Broken Keyboard (a.k.a. Beiju Text)【数组模拟链表】

Broken Keyboard (a.k.a. Beiju Text) You're typing a long text with a broken keyboard. Well it's not so badly broken. The only problem with the keyboard is that sometimes the "home" key or the "end" key gets automatically pressed (inter

Hdu 3887树状数组+模拟栈

题目链接 Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1757    Accepted Submission(s): 582 Problem Description You are given a tree, it’s root is p, and the node is numbered fr

用数组模拟栈的结构

package datastruct; import java.util.Arrays; /** * 用数组模拟栈的结构:后进先出(LIFO) 线性表结构 * @author stone * 2014-07-29 06:34:49 */ public class SimulateStack<E> { public static void main(String[] args) { SimulateStack<String> ss = new SimulateStack<Str

数组模拟堆栈的存储方式代码实践

堆栈的模式是先进后出,取出后堆栈中就没有取出的元素了,所以在模拟时候要注意这些问题. 1 import java.util.Arrays; 2 3 /* 4 5 需求:编写一个类使用数组模拟堆栈的存储方式. 6 7 堆栈存储特点: 先进后出,后进先出. 8 9 注意: 不再使用的对象,应该不要让变量指向该对象,要让该对象尽快的被垃圾回收期回收. 10 11 12 */ 13 class StackList{ 14 15 Object[] elements; 16 17 int index = 0

【Weiss】【第03章】练习3.25:数组模拟队列

[练习3.25] 编写实现队列的例程,使用 a.链表 b.数组 Answer: 在这章一开头就已经写了个链表的队列例程了,所以实际上只要做b小题就可以. 数组模拟队列和链表的两点小不同是: ①.数组空间有限,入队需要检测数组是否已经满 ②.数组经过几次操作后,rear可能绕回front前面,所以许多操作都要用模来实现. 测试代码: 1 #include <iostream> 2 #include "queue.h" 3 using namespace std; 4 usin

串的应用(数组模拟):KMP匹配算法

1 ////////////////////////////////////////////////////////// 2 // String.cpp 3 // 4 // author:Leetao 5 ////////////////////////////////////////////////////////// 6 // 简介: 7 // 串的应用(数组模拟):KMP匹配算法 8 /////////////////////////////////////////////////////

java、C语言实现数组模拟栈

java: public class ArrayStack { private int[] data; private int top; private int size; public ArrayStack(int size) { this.data = new int[size]; this.size = size; this.top = -1; } public boolean isEmpty() { if (this.top == -1) { return true; } return