在C语言中,负数取余
在编译器中,两个异号的数取余之后的结果取决于分子的符号
力扣148. - 力扣(LeetCode)
链表排序。
运用基数排序
struct ListNode* sortList(struct ListNode* head) {
//radix储存基数的头节点,ptr储存尾节点
struct ListNode *radix[10],*ptr[10];
for (int i = 0; i < 10; ++i)
{
radix[i] = (struct ListNode*)malloc(sizeof(struct ListNode));
radix[i]->next = NULL;
ptr[i] = radix[i];
}
//基数排序,cur是排序的节点
struct ListNode*cur = head, *tmp;
for (int i = 1; i <= 100000; i *= 10)
{
while(cur != NULL) //遍历所有的节点,
{
tmp = cur->next;
int px = ((cur->val+100000)/i) % 10;
ptr[px]->next = cur;
cur->next = NULL;
ptr[px] = ptr[px]->next;
cur = tmp;
}
//收集
struct ListNode*prev = ptr[0];
for (int j = 1; j < 10; j++)
{
if(radix[j]->next != NULL) //这里收集节点,
//直接把前一个基数链表的尾节点连接下一个基数链表的有节点(并不是基数链表头节点)。
{
prev->next = radix[j]->next;
prev = ptr[j];
}
}
cur = radix[0]->next;
for (int i = 0; i < 10; ++i)
{
radix[i]->next = NULL;
ptr[i] = radix[i];
}
}
return cur;
}
其中 int px = ((cur->val+100000)/i) % 10; 这句
这句代码是用来计算当前节点cur
在当前基数位i
下的桶索引px
的。让我们逐步解析这句代码:
-
(cur->val + 100000)
: 首先获取当前节点cur
的值,并加上一个足够大的数值100000。这是为了处理负数的情况,将所有数值都转换为非负数。 -
/ i
: 然后将上一步得到的值除以当前基数位i
,这样可以得到当前基数位上的数字。 -
% 10
: 最后对上一步得到的结果取模10,即得到当前基数位上的数字对应的桶索引。
综合起来,这句代码的作用是将当前节点cur
的值根据当前基数位i
进行处理,计算出它在基数排序中对应的桶索引。
基数排序未进行比较大小,题解:. - 力扣(LeetCode)
在使用数组中使用基数排序
int maximumGap(int* nums, int numsSize) {
if (numsSize < 2)
return 0;
int m = INT_MIN;
for (int i = 0; i < numsSize; i++) {
m = fmax(m, nums[i]);
}
int tmp[numsSize];
memset(tmp, 0, sizeof(tmp));
for (int i = 1; i <= m; i *= 10) {
int ptr[10];
memset(ptr, 0, sizeof(ptr));
for (int j = 0; j < numsSize; j++) {
int px = (nums[j] / i) % 10;
ptr[px]++;
}
// 记录节点位置,这里的ptr[k]的值代表该数除以i之后,
//各位是k的基础上的最后一个数是排在整个数组的nums【ptr【k】-1】位置
for (int k = 1; k < 10; k++) {
ptr[k] += ptr[k - 1];
}
// 收集,因为数组的原因从后面开始收集。
for (int j = numsSize - 1; j >= 0; j--) {
int dig = (nums[j] / i) % 10;
tmp[ptr[dig] - 1] = nums[j];
ptr[dig]--;
}
memcpy(nums, tmp, sizeof(int) * numsSize);
}
int max = INT_MIN;
for (int i = 0; i < numsSize - 1; i++) {
if (max < nums[i + 1] - nums[i]) {
max = nums[i + 1] - nums[i];
}
}
return max;
}
这里的难想的就是收集从后面开始收集,如果从前面收集,不知到基数为k该收集到哪里,或者这里从前面一个基数的开始收集(但是还是会错,因为当基数为0时,前一位就会错误,可以分个条件判断。但是这是基数为0的数收集又要一个变量来记录,收集了几个数,所以反倒使代码复杂。