思路
核心思想就是去重和排序
就看去重和排序怎么进行了,哪个在前,哪个在后。
1
简单排序,排序过程中去重 ——————未验证
可以用插入排序,有重复值的时候continue,进行下一个数据的排序。
用折半插入感觉更爽点。哈哈。
其他的冒泡选择什么之类的也可以啦,但是插入最对这个题的胃口的了。读一个数,插入一个,免得重新遍历一遍。
int insert_sort(int a[], int n)
{
int i, j, low, high, mid, temp;
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
temp = a[i];
low = 0;
high = i - 1;
mid = (high + low) / 2;
while(low < high) {
if (temp = a[mid]) {
break;
} else if (temp < a[mid]) {
high = mid -1;
} else {
low = mid + 1;
}
for (j = i; j > high + 1; j--) {
a[j] = a[j - 1];
}
a[j] = temp;
}
}
return 0;
}2
桶排序
a.用1000个桶来统计每个数据的出项次数,输出的时候进行去重。(直接桶排序)
b.用多个桶,每个桶进行插入排序,排序过程中进行去重。(常规桶排序)
a.直接桶排序代码: ——————验证ac
#include<stdio.h>
#include<string.h>
int hash[1001];
int main()
{
int n = 0, i = 0, num = 0;
while(scanf("%d", &n) != EOF) {
memset(hash, 0, sizeof(hash));
for(i = 0; i < n; i++) {
scanf("%d", &num);
hash[num]++;
}
for (i = 1; i < 1001; i++) {
if (hash[i])
printf("%d\n", i);
}
}
return 0;
}b.桶排序加插入排序。 ——————未验证
四个桶来搞吧,个位,十位,百位,千位。怎么有点像基数排序了。得用链表啊。
typedef struct _bucketNum{
int num;
_bucketNum *next;
}bucketNum;
int bucket_sort(int a[], int numLen, int bucketLen)
{
int i, temp, bucket;
bucketNum **bucketPoint = (bucketNum **)malloc(bucketLen * sizeof(bucketNum *));
if (!bucketPoint) {
return -1;
}
for (i = 0; i < bucketLen; i++) {
bucketPoint[i] = (bucketNum *)malloc(sizeof(bucketNum));
if (!bucketPoint[i]) {
while(--i) free(bucketPoint[i]);
free(bucketPoint);
return -1;
}
bucketPoint[i]->num = 0;
bucketPoint[i]->next = null;
}
for (i = 0; i < numLen; i++) {
scanf("%d", &temp);
bucketNum *numNode = (bucketNum *) malloc(sizeof(bucketNum));
numNode->num = temp;
numNode->next = null;
bucket = getBucketNum(numNode->num);//getBucketNum获取位数,就不实现了吧,挺简单的。
bucketPointTemp = bucketPoint[bucket];
if (!bucketPointTemp ->next]) {
bucketPointTemp ->next = numNode;
bucketPoint[bucket]->num++;
} else {
while(!bucketPointTemp->next) {
if (bucketPointTemp->next->num == numNode->num) {
free(numNode);
break;
} else (bucketPointTemp->next->num > numNode->num) {
numNode->next = bucketPointTemp->next;
bucketPointTemp>next = numNode;
bucketPoint[bucket]->num++;
}
bucketPointTemp = bucketPointTemp->next;
}
}
for (i = 0; i < bucketLen ; i++) {
bucketPointTemp = bucketPointTemp[i];
while (!bucketPointTemp->next) {
printf("%d\n", bucketPointTemp->next->num);
bucketPointTemp = bucketPointTemp->next;
bucketPoint[bucket]--;
}
}
freeBucket(bucketPoint);//用完后要全部释放。实现这里就不写了。。。
return 0;}
```
eg:
直接桶排序最简单,插入排序然后去重其次,常规桶排序最长了。
b的桶排序这个并不是针对N<=1000的情况写的。
思考了下这题的变体,如果N比较小,比如说100,并且数据集中分块(10附近一堆,100附近一堆,300一堆这种),用直接桶排序,就是特别合适了。用几个桶就比较合适了,每个桶N个,空间比1000肯定小很多。
其实就是空间和时间的平衡,在平衡中找到最优方式。
直接映射肯定是最方便的,但是空间消耗是最大的;所以需要更改映射方案,但是代价就是增加了一部分的时间开销。

京公网安备 11010502036488号