问题描述
我正在尝试构建霍夫曼树,但是父节点有问题,在某些情况下,它们的起点指向错误的节点(带有字母的节点)。那不应该。怎么回事?我不知道!
UPD:我认为@auth(rules: [{ allow: owner,operations: [create,read,update] }]) { ... }
,while
和extract_min()
在tr_build()
循环中的某个错误。
优先级队列实现了类似指向insert_element()
的指针的数组。
优先级队列工作良好,但是当我尝试构建树时出现问题。
huffman.h
pq_node
huffman.c
#ifndef PRIORITY_QUEUE
#define PRIORITY_QUEUE
#include <stdlib.h>
struct pq_node {
unsigned long frequency;
struct pq_node *parent;
struct pq_node *left;
struct pq_node *right;
char symbol;
};
struct priority_queue {
struct pq_node **heap_on_array;
size_t size;
size_t capacity;
};
// Return 0 if all is OK,-1 if can't alloc pq and -2 if can't alloc pq->heap_on_array.
int init_queue(struct priority_queue **pq,size_t capacity);
void shift_up(struct priority_queue *pq,int i);
void shift_down(struct priority_queue *pq,size_t i);
struct pq_node *extract_min(struct priority_queue *pq);
// Return position if find,or -1 if not.
int find(struct priority_queue *pq,char symbol);
// Return 0 if all is OK,and -1 if we can't alloc memory,if node is not NULL ignore `symbol` and `frequency` and add node.
int insert_element(struct priority_queue *pq,char symbol,unsigned long frequency,struct pq_node *node);
void node_swap(struct pq_node *first,struct pq_node *second);
struct pq_node *tr_build(struct pq_node *first,struct pq_node *second);
#endif
main.c
#include "huffman.h"
int init_queue(struct priority_queue **pq,size_t capacity)
{
(*pq) = malloc(sizeof(struct priority_queue));
if((*pq) == NULL)
{
return -1;
}
(*pq)->heap_on_array = malloc(sizeof(struct pq_node) * capacity);
if((*pq)->heap_on_array == NULL)
{
return -2;
}
for(size_t i = 0; i < capacity; ++i)
{
(*pq)->heap_on_array[i] = malloc(sizeof(struct pq_node));
}
(*pq)->capacity = capacity;
(*pq)->size = 0;
return 0;
}
void shift_up(struct priority_queue *pq,int i)
{
while (pq->heap_on_array[i]->frequency < pq->heap_on_array[(i-1)/2]->frequency)
{
node_swap((pq->heap_on_array[i]),(pq->heap_on_array[(i-1)/2]));
i = (i - 1) / 2;
}
}
void shift_down(struct priority_queue *pq,size_t i)
{
while ((2 * i + 1) < pq->size)
{
size_t left = 2 * i + 1;
size_t right = 2 * i + 2;
size_t j = left;
if((right < pq->size) && (pq->heap_on_array[right]->frequency < pq->heap_on_array[left]->frequency))
{
j = right;
}
if(pq->heap_on_array[i]->frequency <= pq->heap_on_array[j]->frequency)
{
break;
}
node_swap((pq->heap_on_array[i]),(pq->heap_on_array[j]));
i = j;
}
}
struct pq_node *extract_min(struct priority_queue *pq)
{
struct pq_node *tmp = malloc(sizeof(struct pq_node)); //pq->heap_on_array[0];
if(tmp == NULL)
{
return NULL;
}
tmp = pq->heap_on_array[0];
pq->heap_on_array[0] = pq->heap_on_array[pq->size - 1];
pq->size--;
shift_down(pq,0);
return tmp;
}
int find(struct priority_queue *pq,char symbol)
{
for(size_t i = 0; i < pq->size; ++i)
{
if(pq->heap_on_array[i]->symbol == symbol)
{
return (int)i;
}
}
return -1;
}
int insert_element(struct priority_queue *pq,struct pq_node *node)
{
int pos = 0;
if(((pos = find(pq,symbol)) != -1) && (node == NULL))
{
pq->heap_on_array[pos]->frequency+=frequency;
shift_down(pq,pos);
return 0;
}
if(pq->size == pq->capacity)
{
pq->heap_on_array = reallocarray(pq->heap_on_array,pq->size * 2,sizeof(struct pq_node*));
if(pq->heap_on_array == NULL)
{
return -1;
}
pq->capacity = pq->capacity * 2;
for(size_t i = pq->size; i < pq->capacity; ++i)
{
pq->heap_on_array[i] = malloc(sizeof(struct pq_node));
}
}
pq->size++;
if(node == NULL)
{
pq->heap_on_array[pq->size - 1]->symbol = symbol;
pq->heap_on_array[pq->size - 1]->frequency = frequency;
pq->heap_on_array[pq->size - 1]->left = NULL;
pq->heap_on_array[pq->size - 1]->right = NULL;
pq->heap_on_array[pq->size - 1]->parent = NULL;
}
else
{
pq->heap_on_array[pq->size - 1] = node; // Здесь node->paret == NULL. Вот.
}
shift_up(pq,pq->size - 1);
return 0;
}
void node_swap(struct pq_node *first,struct pq_node *second)
{
struct pq_node tmp = *first;
*first = *second;
*second = tmp;
}
struct pq_node *tr_build(struct pq_node *first,struct pq_node *second)
{
struct pq_node *tmp = malloc(sizeof(struct pq_node));
if(tmp == NULL)
{
return NULL;
}
if(first == NULL || second == NULL)
{
return NULL;
}
first->parent = tmp;
second->parent = tmp;
if(first->frequency <= second->frequency)
{
tmp->left = first;
tmp->right = second;
}
else
{
tmp->left = second;
tmp->right = first;
}
tmp->parent = NULL;
tmp->frequency = first->frequency + second->frequency;
tmp->symbol = -1;
return tmp;
}
如果我们在程序末尾查看GDB,我们将看到下一个:
int main()
{
struct priority_queue *pq = NULL;
char code[32] = {'\0'};
init_queue(&pq,1);
insert_element(pq,'a',1,NULL);
insert_element(pq,'b','c','d',NULL);
while (pq->size > 1)
{
struct pq_node *tmp1 = extract_min(pq);
struct pq_node *tmp2 = extract_min(pq);
struct pq_node *tmp3 = tr_build(tmp1,tmp2);
insert_element(pq,-1,tmp3);
}
return 0;
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)