Can';不要从最小堆中删除
所以我必须合并k个排序列表,但为此我必须使用堆结构。在我将每个列表的第一个元素放入堆中之后,我想删除最小的元素,以便继续下一个元素。该算法有效,它删除了第一项,但堆的大小保持不变。当我尝试插入某些内容时,同样适用 举个例子。对于包含以下元素的堆:Can';不要从最小堆中删除,c,C,所以我必须合并k个排序列表,但为此我必须使用堆结构。在我将每个列表的第一个元素放入堆中之后,我想删除最小的元素,以便继续下一个元素。该算法有效,它删除了第一项,但堆的大小保持不变。当我尝试插入某些内容时,同样适用 举个例子。对于包含以下元素的堆: 1 22 0 245 2 277 3 275 输出将如下所示: 0 245 3 275 2 277 3 275 问题是最后一个元素不会被删除,即使我减小了大小 注:第一个数字0、1、2、3表示从中获取这些元素的列表。这是我的源代码: typedef
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;
}
这是一个函数,它应该删除一个元素。min_heapify是有效的,因为我用它做了一些算法,它也有效,我的老师也说了同样的话
堆结构的外观如下:
typedef struct
{
int val, l;
}Heap;
其中val是元素的值,l是从中获取该元素的列表的值
以及测试功能:
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);
构建最小堆(h,k);
printf(“堆:\n”);
for(int i=0;i
其中k是列表数,h[]是堆的结构向量。(堆h[50]) 学习如何使用调试器,然后你可以逐行检查代码,看看哪里出错了。你已经做过了。函数调用结束后,大小返回到4。请发布.C11标准草案n1570:6.5.2.2函数调用,4参数可以是任何完整对象类型的表达式。在准备调用函数时,将计算参数,并为每个参数指定相应参数的值。93)函数可以更改其参数的值,但这些更改不会影响参数的值。C是按价值计算的。哦,我明白了。那么我应该返回新的大小吗?学习如何使用调试器,然后你可以逐行检查代码,看看哪里出错了。已经做过了。函数调用结束后,大小返回到4。请发布.C11标准草案n1570:6.5.2.2函数调用,4参数可以是任何完整对象类型的表达式。在准备调用函数时,将计算参数,并为每个参数指定相应参数的值。93)函数可以更改其参数的值,但这些更改不会影响参数的值。C是按价值计算的。哦,我明白了。那么我应该退回新的尺码吗?
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);