所以我必须合并k排序列表,但为此我必须使用堆结构。在我将每个列表的第一个元素放在堆中后,我想删除最小值,因此我可以继续使用下一个元素。该算法有效,它会删除第一个项目,但堆的大小保持不变。当我尝试插入某些内容时也是如此。
举个例子。对于具有以下元素的堆:
1 22
0 245
2 277
3 275
输出如下:
0 245
3 275
2 277
3 275
问题是即使我减小了大小,也不会删除最后一个元素。
注意:第一个数字0,1,2,3表示从中获取这些元素的列表。这是我的源代码:
typedef struct nod
{
int ch;
struct nod* urm;
}Nod; // structure of a node
typedef struct
{
nod *prim, *ultim;
int nr;
}Lista; // structure of a list
typedef struct
{
int val, l;
}Heap;
Profiler p; // don't mind it, it's for testing purposes only
void creare(Lista l[], int n, int k) // initialization of all lists
{
for (int i = 0; i < n / k; i++)
{
l[i].prim = l[i].ultim = NULL;
l[i].nr = 0;
}
}
Nod *creare_nod(int cheie) // nod creation
{
Nod *nod;
nod = (Nod*)calloc(1, sizeof(Nod));
if (nod != NULL)
{
nod->ch = cheie;
nod->urm = NULL;
}
return nod;
}
void adaugare(Lista l[], int i, Nod *nod) // adding a node in the i'th list
{
if (l[i].prim == NULL) l[i].prim = l[i].ultim = nod;
else
{
nod->urm = l[i].prim;
l[i].prim = nod;
}
l[i].nr++;
}
void afis(Lista l[], int i) // printing the i'th list
{
if (l[i].prim == NULL) printf("Error.");
else
{
Nod *p;
for (p = l[i].prim; p != NULL; p = p->urm)
printf("%d ", p->ch);
}
}
void min_heapify(Heap a[], int n, int i) // Heap propriety
{
int l, r, M; // M - maxim
Heap aux;
l = 2 * i + 1;
r = 2 * i + 2;
M = i;
if (l<n && a[l].val<a[M].val)
M = l;
if (r<n && a[r].val<a[M].val)
M = r;
if (M != i)
{
aux = a[i];
a[i] = a[M];
a[M] = aux;
min_heapify(a, n, M);
}
}
void build_min_heap(Heap a[], int n)
{
for (int i = (n / 2) - 1; i >= 0; i--)
min_heapify(a, n, i);
}
void increase_key(Heap a[], int i, int k, int l)
{
Heap aux;
if (k < a[i].val) return;
a[i].val = k;
a[i].l = l;
while (i > 0 && a[i / 2].val < a[i].val)
{
aux = a[i];
a[i] = a[i / 2];
a[i / 2] = aux;
i = i / 2;
}
}
void insert(Heap a[], int n, int k, int l) // inserts an element in the heap
{
n++;
increase_key(a, n, k, l);
}
void remove_min(Heap a[], int n) // erases the root( minimum )
{
a[0] = a[n - 1];
n--;
if(n>0) min_heapify(a, n, 0);
}
void test()
{
int a[20], n = sizeof(a) / sizeof(a[0]), k = 4;
Lista l[20];
Heap h[50];
Nod *p;
creare(l, n, k);
for (int j = 0; j < k; j++)
{
FillRandomArray(a, n / k, 10, 1000, false, 2);
for (int i = 0; i < n / k; i++)
{
p = creare_nod(a[i]);
adaugare(l, j, p);
}
}
for (int i = 0; i < k; i++)
{
printf("Lista %d: ", i);
afis(l, i);
printf("\n");
}
printf("\n");
for (int i = 0; i < k; i++)
{
h[i].val = l[i].prim->ch;
h[i].l = i;
}
build_min_heap(h, k);
printf("Heap: \n");
for (int i = 0; i < k; i++)
printf("%d %d\n", h[i].l, h[i].val);
remove_min(h, k);
printf("\n\nHeap dupa deletion: \n");
for (int i = 0; i < k; i++)
printf("%d %d\n", h[i].l, h[i].val);
}
int main()
{
test();
printf("\n");
return 0;
}
所以,我刚才所说的简历。
void remove_min(Heap a[], int n)
{
a[0] = a[n - 1];
n--;
min_heapify(a, n, 0);
}
这是函数,它应该删除一个元素。 min_heapify有效,因为我使用了它做了一些算法并且它有效,我的老师也说了同样的事情。
这是堆结构的外观:
typedef struct
{
int val, l;
}Heap;
其中val是元素的值,l是从中获取该元素的list的值。
测试功能:
build_min_heap(h, k);
printf("Heap: \n");
for (int i = 0; i < k; i++)
printf("%d %d\n", h[i].l, h[i].val);
remove_min(h, k);
printf("\n\nHeap after deletion: \n");
for (int i = 0; i < k; i++)
printf("%d %d\n", h[i].l, h[i].val);
其中k是列表的数量,h []是Heap的结构向量。 (堆h [50])。