【问题标题】:Priority Queue and Heap (It's difficult to me..)优先队列和堆(这对我来说很难......)
【发布时间】:2020-06-29 17:31:07
【问题描述】:

我想完成这段代码。

#include <stdio.h>
#include <stdlib.h>

#define HEAP_LEN 100
#define MAX_HEAP 20

struct heapElem{
  int priority;
  char* data;
};

struct _heap{
  int num_data;
  struct heapElem heapArr[HEAP_LEN];
};

int GetPriIdx(struct _heap* ph, int idx);
void swapD(char* a, char* b); 
void swapI(int* a, int* b);
void swap(struct heapElem a, struct heapElem b);
void Insert(struct _heap* ph, char* data, int priority);
void Delete(struct _heap* ph);
void Printout(struct _heap* ph);
void Retrieve(struct _heap* ph);
void KeyIncrease(struct _heap* ph, int priority, int n_priority);

int main(void) {
  struct _heap heap;
  heap.num_data = 0;

  char option_char;
  char name[20];
  int k_value;
  int new_k_value;

  do{
    printf("\n*********** MENU ***************\n");
    printf("I : Insert new element into queue\nD : Delete element with largest key from queue\nR : Retrieve element with largest key from queue\nK : Increase key of element in queue\nP : Print out all elements in queue\nQ : Quit\n\nChoose menu :");
    scanf("%c", &option_char);

    switch(option_char){
      case 'I' : //insert new element into queue
        printf("Enter name of element : ");
        scanf("%s", name);
        printf("Enter key value of element : ");
        scanf("%d", &k_value);
        Insert(&heap, name, k_value);

        break;

      case 'D' : 
        Delete(&heap);
        break;

      case 'R' : 
        Retrieve(&heap);
        break;

      case 'K' : 
        printf("Enter idx of element : ");
        scanf("%d", &k_value);
        printf("Enter new key value : ");
        scanf("%d", &new_k_value);
       KeyIncrease(&heap, k_value, new_k_value);
       break;

     case 'P' : 
        Printout(&heap);
        break;

     default:
          break;

    }


  }while(option_char != 'Q');
  return 0;
}


void swapD(char* a, char* b) {

    char temp = *a;
    *a = *b;
    *b = temp;

}

void swapI(int* a, int* b) {

    int temp = *a;
    *a = *b;
    *b = temp;

}


void Insert(struct _heap* ph, char* data, int priority){
  if(ph->num_data >= MAX_HEAP) return;

  int idx = ph->num_data+1;

  ph->heapArr[idx].data = data;
  ph->heapArr[idx].priority = priority;
  printf("?? instant %d: [%s, %s] \n", idx, ph->heapArr[idx].data, ph->heapArr[idx/2].data);



  while(idx >1 && ph->heapArr[idx].priority > ph->heapArr[idx/2].priority){
    if(priority > ph->heapArr[idx/2].priority){ 
      swapD(ph->heapArr[idx/2].data, ph->heapArr[idx].data);
      swapI(&ph->heapArr[idx/2].priority, &ph->heapArr[idx].priority);
      idx = idx/2;
    }
    else break;
  }

  ph->num_data += 1;
  printf("New element [%s, %d] is inserted.\n",data, priority);

}

我对函数“插入”有疑问:

在这

ph->heapArr[idx].data = data;
ph->heapArr[idx].priority = priority;

不优先, 我只将 'data 放入 idx(如 ph-&gt;heapArr[idx].data = data),但 ph-&gt;Arr 中的所有数据都会更改值。

所有ph-&gt;Arr中仅更改数据。

所以,首先插入 [cat, 5] 第二插入 [dog,9] 然后,它打印 [dog, 9] [dog, 5]

请帮帮我ㅠㅠ

【问题讨论】:

    标签: c queue heap


    【解决方案1】:

    在插入时,当你这样做时:

    ph->heapArr[idx].data = data;
    

    您将 指针 data 分配给堆元素。但是您必须复制数据,否则所有堆元素都指向相同data(在您的主目录中是name)。

    所以你应该这样做:

    ph->heapArr[idx].data = malloc(strlen(data)+1);
    strcpy(ph->heapArr[idx].data, data);
    

    或者您可以使用strdup,它会为您执行此操作:

    ph->heapArr[idx].data = strdup(data);
    

    【讨论】:

    • 真的真的谢谢你!! :> 你的回答对我很有帮助。
    【解决方案2】:

    当您使用此ph-&gt;heapArr[idx].data = data; 时,您不会复制任何数据

    ph-&gt;heapArr[idx].data 你将它指向函数的参数也指向的数据。

    如果你改变那个数据(in main function),那么你也会改变ph-&gt;heapArr[idx].data, 因为您在此指针ph-&gt;heapArr[idx] 中查找变量name 的地址,虽然您可以更改变量name 的值,但所有此数组ph-&gt;heapArr[idx] 仍将指向存储在变量name 地址中的值,所以它们都会改变。

    使用malloc首先为该指针分配内存,而不是将其指向另一个变量,在其中存储数据(复制数据而不仅仅是指向数据)

    ph->heapArr[idx].data = malloc(strlen(data)+1);
    strcpy(ph->heapArr[idx].data, data);
    
    

    【讨论】:

    • 真的真的非常感谢!! :> 你的回答对我很有帮助。
    • @Yeong 随意,无需感谢。如果真的帮助你接受答案。
    猜你喜欢
    • 2019-06-10
    • 2017-10-18
    • 1970-01-01
    • 2011-12-16
    • 2011-06-09
    • 2013-09-30
    • 2018-12-24
    • 2016-01-19
    • 1970-01-01
    相关资源
    最近更新 更多