无法从最小堆中删除

时间:2016-03-31 12:46:35

标签: c

所以我必须合并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])。

0 个答案:

没有答案