ReviewForJob——桶式排序+基数排序(==多次桶式排序)

【0】README

1)本文旨在 给出 ReviewForJob——桶式排序+基数排序(==多次桶式排序) 的 代码实现和代码分析;

2)桶式排序基础参见 http://blog.csdn.net/pacosonswjtu/article/details/49685749, 基数排序基础参见  http://blog.csdn.net/pacosonswjtu/article/details/49687193


【1】桶式排序

1)intro:桶式排序适用于 许多输入只是一些小的整数的case, 而这种输入数据是 小整数的case 下 使用 快速排序就小题大做了;(小整数,比如所有数据小于10)

2)输入数据: 输入数据 A1, A2, A3, ........,An 必须只由小于 M 的整数组成;因为桶只有 M 个,M 个 桶存储在数组中;如对10进制数字而言,桶取10;纸牌数字而言,桶取13;纸牌花色而言,桶取4;(你看到了,生活中,小整数本就直接或间接存在的)

3)桶式排序如何存储数据的? value == index(把value看做其存储在数组中的下标)(干货——桶式排序的核心)即 array[Ai] = Ai,如 array[1] = 1,对的,你没有看错,数字1 就存储在 下标为1的桶中,或以下标为1的链表中(链式存储);如果有多个1的话,就存储在 其 next 节点中;这样一来,头结点存储在数组下标为1的 链表 存储着输入的所有数字1;

4)源码实现如下:

#include <stdio.h>
#include <malloc.h>#define ElementType int
#define Error(str) printf("\n\t error: %s \n",str) struct Node;
typedef struct Node *Node;struct Node
{int value;Node next;
};struct BucketSet;
typedef struct BucketSet* BucketSet;struct BucketSet
{int size;Node* array;
};BucketSet initBucketSet();
void printArray(ElementType* data, int size);
Node createNode(int value);
void bucketsort(Node* buckets, ElementType value);// allocate for new Node with value.
Node createNode(int value)
{Node temp = (Node)malloc(sizeof(struct Node));if(temp==NULL){Error("failed createBucket() for out of space.");return NULL;}temp->next = NULL;temp->value = value;return temp;
}// allocate the memory for the bucket and bucket ptr
BucketSet initBucketSet(int size)
{BucketSet bucketSet;	int i;// allocate memory for BucketSet.bucketSet = (BucketSet)malloc(sizeof(struct BucketSet));if(bucketSet==NULL){Error("failed initBucketSet() for out of space.");return NULL;	}bucketSet->size = size;// allocate memory for BucketSet->buckets.bucketSet->array = (Node*)malloc(size * sizeof(Node));if(!bucketSet->array){Error("failed initBucketSet() for out of space.");return NULL;	}	// allocate memory for every unit in BucketSet->buckets.for(i=0; i<size; i++){bucketSet->array[i] = createNode(-1);if(bucketSet->array[i]==NULL){			Error("failed initBucketSet() for out of space.");return NULL;}		}return bucketSet;
}// details of bucketSort for the input array data with size
void bucketsort(Node* buckets, ElementType value)
{			Node temp = buckets[value]; // value is treated as index.while(temp->next){temp = temp->next;}temp->next = createNode(value);temp->next->value = value;
}
// 将桶中数据 copy 回 原来的数组中.
void bucketsToArray(BucketSet bucketSet, ElementType* array)
{Node* buckets = bucketSet->array;Node temp;int size = bucketSet->size;int i, j=0;for(i=0; i<size; i++){temp = buckets[i];while(temp->next){			array[j++] = temp->next->value;temp = temp->next;}}
}void printArray(ElementType* data, int size)
{int i;for(i = 0; i < size; i++)	 printf("\n\t data[%d] = %d", i, data[i]);					 printf("\n\n");
} 
#include "p189_bucket_sort.h"void main()
{ 	BucketSet bucketSet;ElementType data[] = {9, 6, 3, 2, 7, 7, 1, 4, 1, 0, 3, 9, 1, 1};	int	size = 14, capacity=10;int i;bucketSet = initBucketSet(capacity);if(bucketSet==NULL){return ;}  printf("\nbucketsort based on {9, 6, 3, 2, 7, 7, 1, 4, 1, 0, 3, 9, 1, 1}\n");	// 对10以内的数字进行桶排序.for(i=0; i<size; i++){bucketsort(bucketSet->array, data[i]);	}	bucketsToArray(bucketSet, data);printArray(data, size);	
} 


对以上代码的分析(Analysis):void bucketsort(Node* buckets, ElementType value) :桶排序的函数声明 必须这样写,因为main 函数中通过循环传入输入数据就可以调用了,这也方便了 后续 基数排序的扩展,即 不要把 main函数中的循环 放入 bucketsort() 函数中去;


【2】基数排序

1)intro:基数排序等价于多次桶式排序;

2)基数排序中的桶式排序代码和 单纯的桶式排序代码有一点不一样:下面的代码可以看到, 基数排序中的桶式排序方法 一开始就要 计算 输入数据在某位上的数字,该数字作为 index 而不是整个 value 作为 index, 这和 单纯的桶式排序有点区别;

// get the integer under the bit.
int singleBit(int value, int bit)
{int i=1;while(i++ < bit){value /= 10;}return value%10;
}// details of bucketsort for input data. 
void bucketsort(Node* buckets, ElementType value, int bit) // 基数排序中的桶式排序代码
{			int index = singleBit(value, bit);Node temp = buckets[index]; // value is treated as direct or indirect index.while(temp->next){temp = temp->next;}temp->next = createNode(value);	
}
// details of bucketSort for the input array data with size
void bucketsort(Node* buckets, ElementType value) // 单纯的桶式排序代码
{			Node temp = buckets[value]; // value is treated as index.while(temp->next){temp = temp->next;}temp->next = createNode(value);temp->next->value = value;
}
3)基数排序代码如下:
// get the integer under the bit.
int singleBit(int value, int bit)
{int i=1;while(i++ < bit){value /= 10;}return value%10;
}// details of bucketsort for input data. 
void bucketsort(Node* buckets, ElementType value, int bit)
{			int index = singleBit(value, bit);Node temp = buckets[index]; // value is treated as direct or indirect index.while(temp->next){temp = temp->next;}temp->next = createNode(value);	
}
#include "p189_bucket_sort.h"//free the memory bucketSet->array own.
void clearBuckets(BucketSet bucketSet)
{int i, size = bucketSet->size;Node* array = bucketSet->array;Node temp, tempcopy;for(i=0; i<size; i++){temp = array[i]->next;while(temp){tempcopy = temp;temp = temp->next;free(tempcopy);tempcopy = NULL;			}array[i]->next = NULL;}
}// 基于桶式排序的基数排序. (待排序元素个数为size)
void radixsort(ElementType* array, int size)
{BucketSet bucketSet;	int	capacity=10; // 桶的设置为 10.int i, j;bucketSet = initBucketSet(capacity);if(bucketSet==NULL){return ;}  for(i=1; i<=3; i++){for(j=0; j<size; j++){bucketsort(bucketSet->array, array[j], i);}bucketsToArray(bucketSet, array); // 别忘记将桶中数据copy 回数组.printArray(array, size);	clearBuckets(bucketSet); // 每轮都要清理 数组式链表.}
}
void main()
{ 		 ElementType array[] = {110, 245, 895, 658, 321, 852, 147, 458, 469, 159, 347, 28};	int size=12;printf("\n radix sort based on {110, 245, 895, 658, 321, 852, 147, 458, 469, 159, 347, 28}\n");	radixsort(array, size);			
} 




本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330974.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring boot(3):Spring boot中Redis 的使用

Spring boot除了常用的数据库支持外&#xff0c;对nosql数据库也进行了封装自动化。 1 Redis介绍 Redis 是目前业界使用最广泛的内存数据存储。相比memcached&#xff0c; &#xff08;1&#xff09;Redis支持更丰富的数据结构&#xff0c;例如hashes&#xff0c;lists&#x…

Java List面试题汇总

转载自 Java List面试题汇总 1、你知道的List都有哪些&#xff1f; 2、List和Vector有什么区别&#xff1f; 3、List是有序的吗&#xff1f; 4、ArrayList和LinkedList的区别&#xff1f;分别用在什么场景&#xff1f; 5、ArrayList和LinkedList的底层数据结构是什么&#…

ReviewForJob——拓扑排序+最短路径算法(有权+无权)

【0】README 1&#xff09;本文旨在给出 拓扑排序最短路径算法&#xff08;有权无权&#xff09; 的源码实现 和 分析&#xff0c;内容涉及到 邻接表&#xff0c; 拓扑排序&#xff0c; 循环队列&#xff0c;无权最短路径&#xff08;广度优先搜索&#xff09;&#xff0c;有权…

Spring boot (5):Spring data jpa 的使用

总结&#xff1a; jpa是什么&#xff0c;spring data jpa是什么&#xff1f; jpa是一套规范&#xff0c;不是一套产品。jpa是一套规范&#xff0c;不是一套产品。 spring data jpa是spring基于ORM框架、JPA规范的基础上封装的一套JPA应用框架&#xff0c;提供了包括增删改等在…

Java Map集合面试题汇总

转载自 Java Map集合面试题汇总1、 你都知道哪些常用的Map集合?2、Collection集合接口和Map接口有什么关系&#xff1f;3、HashMap是线程安全的吗&#xff1f;线程安全的Map都有哪些&#xff1f;性能最好的是哪个&#xff1f;4、使用HashMap有什么性能问题吗&#xff1f;5、Ha…

ReviewForJob——二叉堆优先队列的实现(三种堆节点类型——int + struct HeapNode + struct HeapNode*)

【0】README 1&#xff09;本文旨在给出 二叉堆优先队列的实现 的代码实现和分析&#xff0c; 而堆节点类型 不外乎三种&#xff1a; 一&#xff0c; 基本类型如int&#xff1b; 二&#xff0c;结构体类型 struct HeapNode&#xff1b; 三&#xff0c;结构体指针类型 struct H…

Spring boot(六):如何优雅的使用mybatis

总结 hibernate 和 mybatis 的区别 hibernate的特点是所有的sql都用java代码生成&#xff0c;不用跳出程序去&#xff08;看&#xff09;sql&#xff0c;发展到最顶端就是Spring data jpa了。 mybatis初期使用比较麻烦&#xff0c;需要各种配置文件、实体类、dao层映射关联、还…

Java中创建String的两道面试题及详解

转载自 Java中创建String的两道面试题及详解 我们知道创建一个String类型的变量一般有以下两种方法&#xff1a; String str1 "abcd";String str2 new String("abcd"); 那么为什么会存在这两种创建方式呢&#xff0c;它们在内存中的表现形式各有什么区别…

ReviewForJob——最小生成树(prim + kruskal)源码实现和分析

【0】README 1&#xff09;本文旨在给出 ReviewForJob——最小生成树&#xff08;prim kruskal&#xff09;源码实现和分析&#xff0c; 还会对其用到的 技术 做介绍&#xff1b; 2&#xff09;最小生成树是对无向图而言的&#xff1a;一个无向图G 的最小生成树是一个连通图…

Spring boot(七):Spring boot+ mybatis 多数据源最简解决方案

多数据源一般解决哪些问题&#xff1f;主从模式或者业务比较复杂需要连接不同的分库来支持业务。 直接上代码。 配置文件 pom包依赖&#xff0c;该依赖的依赖。主要是数据库这边的配置&#xff1a; mybatis.config-locationsclasspath:mybatis/mybatis-config.xmlspring.da…

Java:关于main方法的10道面试题

转载自 Java&#xff1a;关于main方法的10道面试题 1.main方法是做什么用的&#xff1f; 2.不用main方法如何运行一个类&#xff1f; 3.main方法如何传递参数&#xff1f;传递参数的类型是什么&#xff1f;能不能改变该参数类型&#xff1f; 4.main方法为什么是静态的&#xff…

ReviewForJob——深度优先搜索的应用

【0】README 1&#xff09;本文旨在 介绍 ReviewForJob——深度优先搜索的应用 及其 源码实现 &#xff1b; 2&#xff09;搜索树的技术分为广度优先搜索 和 深度优先搜索&#xff1a;而广度优先搜索&#xff0c;我们前面利用 广度优先搜索计算无权最短路径已经做过分析了&am…

Spring boot(八):RabbitMQ详解

RabbitMQ介绍 RabbitMQ既一个消息队列&#xff0c;主要用来实现应用程序的异步和解耦&#xff0c;同时也能起到消息缓冲&#xff0c;消息分发的作用。 消息中间件在互联网公司的使用中越来越多。消息中间件最主要的作用是解耦&#xff0c;中间件最标准的用法师生产者生产消息传…

关于Jvm知识看这一篇就够了

转载自 关于Jvm知识看这一篇就够了2016年左右的时候读了周志明《深入理解Java虚拟机&#xff1a;JVM高级特性与最佳实践》&#xff0c;读完之后受益匪浅&#xff0c;让我对Java虚拟机有了一个完整的认识&#xff0c;这是Jvm书籍中最好的读物之一。后来结合实际工作中遇到的问题…

ReviewForJob——算法设计技巧(贪婪算法+分治算法+动态规划)

【0】README 1&#xff09;本文旨在介绍算法设计技巧包括 贪婪算法、分治算法、动态规划 以及相关的荔枝等&#xff1b; 【1】贪婪算法 1&#xff09;intro&#xff1a; 贪婪算法是分阶段进行的&#xff0c;在每个阶段&#xff0c;可以认为所做的决定是最好的&#xff0c;而…

Spring boot(九):定时任务

在我们的项目开发过程中&#xff0c;进场需要定时任务来帮助我们做一些内容&#xff0c;springboot默认已经帮我们实行了&#xff0c;只要天剑相应的注解就可以实现。 1、pom包配置 pom包里面只需要引入springboot starter包即可 <dependencies><dependency><…

jvm系列(一):java类的加载机制

转载自 jvm系列(一):java类的加载机制1、什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中&#xff0c;将其放在运行时数据区的方法区内&#xff0c;然后在堆区创建一个 java.lang.Class对象&#xff0c;用来封装类在方法区内的数据结构。类的加载的最…

Springboot(十):邮件服务

发送邮件应该是网站的必备功能之一&#xff0c;什么注册验证&#xff0c;忘记密码或者是给用户发送营销信息。最早期的时候我们会使用javaMail相关api来写邮件相关代码&#xff0c;后来spring退出了javaMailSender 更加简化了邮件发送的过程&#xff0c;在之后springboot 对此进…

How to install plugin for Eclipse from .zip

these contents are reshiped from 如何在eclipse中安装.zip插件 1.make sure your .zip file is an valid Eclipse Plugin Note: that means: your .zip file contains folders features and plugins, like this:for new version Eclipse Plugin, it may also include anothe…

jvm系列(二):JVM内存结构

转载自 jvm系列(二):JVM内存结构所有的Java开发人员可能会遇到这样的困惑&#xff1f;我该为堆内存设置多大空间呢&#xff1f;OutOfMemoryError的异常到底涉及到运行时数据的哪块区域&#xff1f;该怎么解决呢&#xff1f;其实如果你经常解决服务器性能问题&#xff0c;那么这…