警告:这是基于您对希望打印“已更改”索引(与您问题中的“未更改/零”索引相比)的最高评论。
这可以在O(k) 时间复杂度和O(2n) 空间复杂度下完成。
鉴于原始数组 arr[n],我们需要一个额外的数组来跟踪 k 更改的索引。
无论如何,这是带有随机测试套件的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
enum {
n = 100
};
int opt_s; // 0=unsorted, 1=qsort, 2=insertion
int opt_v; // verbose/debug printing
int opt_n; // number of array elements
int seed; // random seed
// node to keep track of changed indexes
// NOTE: next is only needed for sort mode 2
typedef struct node node_t;
struct node {
int idx;
node_t *next;
};
int *arr; // original array
node_t *nzlist; // list of changed indexes
int k; // number of changed indexes
node_t *head; // head of list (sort mode 2)
void
add(int i)
{
int oval = arr[i]++;
node_t *newnode;
node_t *cur;
node_t *prev;
do {
if (oval)
break;
if (opt_v)
printf("add: k=%d i=%d\n",k,i);
newnode = &nzlist[k++];
newnode->idx = i;
if (opt_s != 2)
break;
// find sorted insertion point
prev = NULL;
for (cur = head; cur != NULL; cur = cur->next) {
if (cur->idx > i)
break;
prev = cur;
}
newnode->next = cur;
// empty list -- set the head
if (prev == NULL)
head = newnode;
// insert before cur
else
prev->next = newnode;
} while (0);
}
int
sortcmp(const void *vplhs,const void *vprhs)
{
const node_t *lhs = vplhs;
const node_t *rhs = vprhs;
int cmpflg;
cmpflg = lhs->idx - rhs->idx;
return cmpflg;
}
void
sortlist(void)
{
qsort(nzlist,k,sizeof(node_t),sortcmp);
}
void
print_link(void)
{
node_t *cur;
for (cur = head; cur != NULL; cur = cur->next)
printf("%d\n",cur->idx);
}
void
print_linear(void)
{
node_t *cur;
for (cur = &nzlist[0]; cur < &nzlist[k]; ++cur)
printf("%d\n",cur->idx);
}
int
main(int argc,char **argv)
{
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
char *cp = *argv;
if (*cp != '-')
break;
cp += 2;
switch(cp[-1]) {
case 'n':
opt_n = (*cp != 0) ? atoi(cp) : 300;
break;
case 's':
opt_s = (*cp != 0) ? atoi(cp) : 1;
break;
case 'R':
seed = (*cp != 0) ? atoi(cp) : 0;
break;
case 'v':
opt_v = (*cp != 0) ? atoi(cp) : 1;
break;
}
}
if (opt_n <= 0)
opt_n = 20;
printf("n = %d\n",opt_n);
arr = calloc(opt_n,sizeof(*arr));
nzlist = calloc(opt_n,sizeof(*nzlist));
if (seed == 0)
seed = time(NULL);
printf("R = %d\n",seed);
srand(seed);
int rounds = rand() % (opt_n / 2);
for (int iround = 0; iround < rounds; ++iround) {
int idx = rand() % opt_n;
add(idx);
}
switch (opt_s) {
case 0: // unsorted
print_linear();
break;
case 1: // sorted by qsort
sortlist();
print_linear();
break;
case 2: // insertion sort in linked list
print_link();
break;
}
return 0;
}