hash+链表排序

5 篇文章 0 订阅

传送门https://pintia.cn/problem-sets/1136515446447235072/problems/1136531088437108736

这道题真的出得跟shi一样

 

说好的给出,但只要信了就会WA两个点(手动微笑

题目本身不难

把名字hash一下,然后用vector排个序就ojbk了,甚至可以用优先队列

可是

大后天的数据结构机考不让用C++,只能用C

这是逼着让人手写链表排序woc

写就写吧 反正又不是没写过 上次写链表排序好像debug到凌晨两三点呜呜呜

然后就:

真爽

bug1:没有注意头指针为空

bug2:sort排序没有更新头指针的值

这就暴露出对递推的理解还是不够深,而且,太依赖C++的库函数了呜呜呜不让用C++的库函数可太惨了

唉 直接贴C的代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXN 180000
typedef struct Hash{
	int val;
	struct Hash *next;
}Hash;
Hash *hash[MAXN]; 
int to_num(char *s){//将名字hash成数字 最大hash(zzz9) = 175759
	int sum = 0;
	for(int i = 0; i < 3; ++i) sum = sum * 26 + s[i] - 'A';
	sum = sum * 10 + s[3] - '0';
	return sum;
}
void push(int id, int x){
	if(hash[id] == NULL){//一定要注意最开始头指针为空
		hash[id] = (Hash *)malloc(sizeof(Hash));
		hash[id]->next = NULL;
		hash[id]->val = x;
		return;
	}
	Hash *p = hash[id];
	while(p->next != NULL) p = p->next;
	p->next = (Hash *)malloc(sizeof(Hash));
	p->next->next = NULL;
	p->next->val = x;
}
int size(Hash *p){//链表长度 
	int cnt = 0;
	while(p != NULL){
		p = p->next;
		cnt++;
	}
	return cnt;
}
//链表的冒泡排序 
Hash *bubble(Hash *p){ 
	if(p->next != NULL && p->next->next != NULL) p->next = bubble(p->next);//递推冒泡,从尾端开始 
	if(p->val > p->next->val){//swap 
		Hash *str = p->next;
		p->next = str->next;
		str->next = p;
		return str; 
	}
	return p;
}
Hash *sort(Hash *p){
	if(p != NULL && p->next != NULL){
		p = bubble(p);//用冒泡将最小值冒到p位置,并更新p!!! 
		p -> next = sort(p->next);//然后递推下一个位置,并更新p->next!!! 
	}
	return p;
}
void print(char *name, int id){
	Hash *p = hash[id];
	printf("%s %d", name, size(p));
	p = sort(p);//sort后原来p不一定在头部,所以一定要更新p 
	while(p != NULL){
		printf(" %d", p->val);
		p = p->next;
	} 
	printf("\n");
}
int main(){
	int n, k, t, id, c;
	char name[10];
	scanf("%d%d", &n, &k);
	memset(hash, (0, NULL), sizeof(Hash));
	for(int i = 1; i <= k; i++){
		scanf("%d%d", &c, &t);//虽然题目说的是顺序给出课程1~K是选课学生名单,但你要信了就WA了 
		while(t--){
			scanf("%s", name);
			id = to_num(name);//将学生名字hash成id 
			push(id, c);//将课程加入学生链表 
		}
	}
	scanf("%d", &n);
	while(n--){
		scanf("%s", &name);
		id = to_num(name);
		print(name, id);
	}
	return 0;
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值