基数排序之代码优化

很久之前写过关于基于基数排序的代码实现。那时候还年轻不懂事,最近无意中与同事聊起,把百度基数排序看了一遍,又想起之前敲过的代码,回头翻出来看了一遍,发现还很粗糙,完全不能看的节奏。

 我以前敲代码用到链表,发现还不错,就想着用链表去实现一遍。好久没用链表了,都有点忘了,花了些时间是把思维理清。链表LinkList采用的是双端链表,从链表的尾部添加,头部拿出来,每拿出一个就去掉一个Link(这是为了保存数据的稳定性)。

public class RadixSort {
	private static LinkList[] linkList= new LinkList[10];
	static{
		for(int i = 0 ; i < 10 ; i++){
			linkList[i] = new LinkList();
		}
	}
	
	public static void clear(){
		for(int i = 0 ; i < 10 ; i++){
			linkList[i].clear();
		}
	}
	
	/** 与百度基数排序一致的想法实现*/
	public static void sort(int[] number,int q) 
	{	
		int num = number.length;
		int d = 1; 
		int t = 0;
		int temp;
		while(q > 0){
			for(int i = 0 ; i < num ; i++){
			    temp = (number[i]/d) % 10;
					linkList[temp].insertLast(number[i]);
			}
			for(int k = 0 ; k < 10 ; k++){
				while((temp = linkList[k].popFirst())!= -1){
					number[t++] = temp;
				}			
			}
			t = 0;
			d = d*10;
			q--;
		}
		clear();
	}
}public static void sort(int[] number ){
		 int len = number.length;
		 int[] sorted = new int[len];//已排好序的数组
		 int num = len;//还剩多少要排序的,动态变
		 int d = 1; //位
		 int temp;
		 int num1 = num;//每一轮要排序的长度
		 int t ;
		 while(num1 > 0 ){
			 for(int i = 0 ; i < num1 ; i++){
				 temp = number[i] / d;
				 if(temp == 0){
					 sorted[len - num] = number[i];
					 num --;
				 }else{
					 temp = temp % 10;
					 linkList[temp].insertLast(number[i]);
				 }
			 }
			 num1 = num;
			 t = 0;
			 for(int k = 0 ; k < 10 ; k++){
					while((temp = linkList[k].popFirst())!= -1){
						number[t++] = temp;
					}			
			}
			d = d * 10;		
		 }
		clear();		
		//number = sorted;这样子是不行的
		for(int i = 0 ; i < len ; i++){
			number[i] = sorted[i];
		}		
	}/**
	 *  不知道位数的基数排序
	 */
	public static void sort(int[] number ){
		 int len = number.length;//数组长度
		 int num = 0 ;//已排好序的个数
		 int d = 1; //位
		 int temp; //临时变量,看环境而变
		 int t ; //临时变量,看环境而变
		 while(num < len ){
			 for(int i = num ; i < len ; i++){
				 temp = number[i] / d;
				 if(temp == 0){
					 number[num++] = number[i];
				 }else{
					 temp = temp % 10;
					 linkList[temp].insertLast(number[i]);
				 }
			 }
			 t = num;
			 for(int k = 0 ; k < 10 ; k++){
					while((temp = linkList[k].popFirst())!= -1){
						number[t++] = temp;
					}			
			}
			d = d * 10;		
		 }
		clear();				
	}/** 
	 * 已知道位数的基数排序
	 */
	public static void sort(int[] number,int maxd ){
		 int len = number.length;//数组的长度
		 int num = 0 ;//已排好序的个数
		 int d = 1; //位
		 int temp; //临时变量,看环境
		 int temp1 ;//临时变量,看环境
		for(int j = 0 ; j < maxd; j++){
			 for(int i = num ; i < len ; i++){
				 temp = number[i] / d;
				 if(temp == 0){ //已经没有更多位了
					 number[num++] = number[i];
				 }else{
					 temp = temp % 10;
					 linkList[temp].insertLast(number[i]);
				 }
			 }
			 temp1 = num;
			 for(int k = 0 ; k < 10 ; k++){
					while((temp = linkList[k].popFirst())!= -1){
						number[temp1++] = temp;
					}			
			 }
			d = d * 10;		
		 }
		clear();				
	}public static int getRadix(int[] number){
		int temp = number[0];
		int index = 0;//位数
		/** 查出最大的数 */
		for(int i = 1 ; i < number.length ; i++){
			if(temp < number[i]){
				temp = number[i];
			}
		}
		do{
			index++;
			temp /= 10;
		}while(temp > 0);
		
		return index;
	}public class Link {
	public int idata;
	public Link next = null;
	public Link(int idata){
		this.idata = idata;
	}
}
/** 采用在尾部last添加,从头部first拿出*/
public class LinkList {
	public Link first = null;
	public Link last = null;
	
	public LinkList(){}
	
	public void insertLast(int idata){
		Link link = new Link(idata);
		if(last == null){
			first =  link;
		}else{
			last.next = link;
		}	
		last = link;		
	}
	
	/**如果没有数则返回-1 */
	public int popFirst(){		
		if(first != null){
			if(last == first){
				last = null;
			}
			int temp = first.idata;
			first = first.next;
			return temp;
		}
		return -1;
	}
	
	public void clear(){
		first = null;
		last = null;
	}
	
	public void print(){
		Link temp = first;
		while(temp!= null){
			System.out.print(temp.idata +  "  ");
			temp = temp.next;
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是基于链式基数排序和折半查找实现汽车牌照数据排序和快速查找的完整代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> // 定义车辆信息结构体 typedef struct car_info { char plate_number[8]; // 汽车牌照号码 char owner_name[20]; // 车主姓名 char brand[20]; // 汽车品牌 int price; // 汽车价格 } CarInfo; // 定义链表节点结构体 typedef struct node { CarInfo car; // 车辆信息 struct node *next; // 下一个节点指针 } Node; // 定义哈希表结构体 typedef struct hash_table { int size; // 哈希表大小 Node **table; // 存储节点指针的数组 } HashTable; // 哈希函数:将牌照号码转换为哈希值 int hash(char *plate_number, int size) { int sum = 0; for (int i = 0; i < strlen(plate_number); i++) { sum += plate_number[i]; } return sum % size; } // 初始化哈希表 HashTable *init_hash_table(int size) { HashTable *hash_table = (HashTable *) malloc(sizeof(HashTable)); hash_table->size = size; hash_table->table = (Node **) malloc(sizeof(Node *) * size); for (int i = 0; i < size; i++) { hash_table->table[i] = NULL; } return hash_table; } // 创建节点 Node *create_node(CarInfo car) { Node *node = (Node *) malloc(sizeof(Node)); node->car = car; node->next = NULL; return node; } // 向哈希表中插入节点 void insert_node(HashTable *hash_table, CarInfo car) { int index = hash(car.plate_number, hash_table->size); Node *node = hash_table->table[index]; if (node == NULL) { hash_table->table[index] = create_node(car); } else { while (node->next != NULL) { node = node->next; } node->next = create_node(car); } } // 从哈希表中查找节点 Node *find_node(HashTable *hash_table, char *plate_number) { int index = hash(plate_number, hash_table->size); Node *node = hash_table->table[index]; while (node != NULL) { if (strcmp(node->car.plate_number, plate_number) == 0) { return node; } node = node->next; } return NULL; } // 销毁哈希表 void destroy_hash_table(HashTable *hash_table) { for (int i = 0; i < hash_table->size; i++) { Node *node = hash_table->table[i]; while (node != NULL) { Node *temp = node; node = node->next; free(temp); } } free(hash_table->table); free(hash_table); } // 获取牌照号码的指定位上的数字 int get_digit(char *plate_number, int digit) { if (digit < strlen(plate_number)) { return plate_number[strlen(plate_number) - digit - 1] - '0'; } else { return 0; } } // 链式基数排序 void radix_sort(HashTable *hash_table, int digit) { int counts[10] = {0}; Node *buckets[10] = {NULL}; for (int i = 0; i < hash_table->size; i++) { Node *node = hash_table->table[i]; while (node != NULL) { int d = get_digit(node->car.plate_number, digit); if (buckets[d] == NULL) { buckets[d] = create_node(node->car); } else { Node *temp = buckets[d]; while (temp->next != NULL) { temp = temp->next; } temp->next = create_node(node->car); } node = node->next; } } for (int i = 0; i < 10; i++) { counts[i] = 0; } for (int i = 0; i < 10; i++) { Node *node = buckets[i]; while (node != NULL) { int index = hash(node->car.plate_number, hash_table->size); Node *temp = hash_table->table[index]; while (temp != NULL) { if (strcmp(temp->car.plate_number, node->car.plate_number) == 0) { temp->car = node->car; break; } temp = temp->next; } node = node->next; } } for (int i = 0; i < 10; i++) { Node *node = buckets[i]; while (node != NULL) { Node *temp = node; node = node->next; free(temp); } } if (digit > 0) { radix_sort(hash_table, digit - 1); } } // 折半查找 Node *binary_search(HashTable *hash_table, char *plate_number) { int left = 0, right = hash_table->size - 1; while (left <= right) { int mid = (left + right) / 2; Node *node = hash_table->table[mid]; while (node != NULL) { if (strcmp(node->car.plate_number, plate_number) == 0) { return node; } else if (strcmp(node->car.plate_number, plate_number) < 0) { node = node->next; } else { break; } } if (node == NULL || strcmp(node->car.plate_number, plate_number) > 0) { right = mid - 1; } else { left = mid + 1; } } return NULL; } // 打印车辆信息 void print_car_info(CarInfo car) { printf("Plate number: %s, Owner name: %s, Brand: %s, Price: %d\n", car.plate_number, car.owner_name, car.brand, car.price); } int main() { // 初始化哈希表 HashTable *hash_table = init_hash_table(100); // 构造车辆信息 CarInfo car1 = {"A123456", "Tom", "Toyota", 200000}; CarInfo car2 = {"B234567", "John", "Honda", 150000}; CarInfo car3 = {"C345678", "Mary", "BMW", 300000}; CarInfo car4 = {"D456789", "Lucy", "Audi", 250000}; // 向哈希表中插入车辆信息 insert_node(hash_table, car1); insert_node(hash_table, car2); insert_node(hash_table, car3); insert_node(hash_table, car4); // 链式基数排序 radix_sort(hash_table, 6); // 折半查找 Node *node1 = binary_search(hash_table, "A123456"); Node *node2 = binary_search(hash_table, "C345678"); // 打印查找到的车辆信息 if (node1 != NULL) { print_car_info(node1->car); } else { printf("Car not found.\n"); } if (node2 != NULL) { print_car_info(node2->car); } else { printf("Car not found.\n"); } // 销毁哈希表 destroy_hash_table(hash_table); return 0; } ``` 以上代码中,我们首先定义了车辆信息结构体和链表节点结构体,并使用哈希表来存储节点。在哈希表中,我们使用链式法解决哈希冲突,即当两个不同的牌照号码映射到同一个哈希值时,将它们放在同一个链表中。 然后,我们实现了哈希函数、初始化哈希表、创建节点、向哈希表中插入节点、从哈希表中查找节点、销毁哈希表等操作。其中,哈希函数使用了简单的取余方法,可以根据实际需求进行优化。 接着,我们实现了链式基数排序和折半查找。链式基数排序是基于哈希表的排序算法,可以根据汽车牌照号码的每一位进行排序。折半查找是一种高效的查找算法,可以在排序好的数组或链表中查找指定元素。 最后,我们构造了一些车辆信息,向哈希表中插入节点,并进行链式基数排序和折半查找。如果找到了指定的车辆信息,则打印其详细信息;否则输出“Car not found.”。最后,我们销毁哈希表,释放内存。 需要注意的是,以上代码仅供参考,实际应用中可能需要根据实际需求进行修改和优化

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值