Can';不要从最小堆中删除

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

所以我必须合并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;
 }
这是一个函数,它应该删除一个元素。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);