第一步,初始化:首先我们需要初始化一个队列,该队列将用于辅助构建哈夫曼树。然后,我们将每个字符的权值作为叶子结点的值创建成单节点的二叉树,并将这些节点的二叉树依次加入到队列当中。
第二步,构建哈夫曼树:接下来,我们循环执行以下步骤直到队列中只剩下一个节点(哈夫曼树的根节点):
1.从队列中选取权值最小的两个节点,分别作为新节点的左右子树。
2.创建一个新节点,将这两个节点连接到新节点的左右子树的位置上。
3.将新节点加入到队列中。
第三步,获取哈夫曼树的根节点:当队列中只剩下一个节点时,这个节点就是哈夫曼树的根节点,我们可以将她从队列中取出,作为整个哈夫曼树的根节点。
这样,利用二叉树存储哈夫曼的过程就完成了。整个过程是按照哈夫曼树构建的规则,从下往上逐步构建树的结构,确保了树的叶子结点对应字符的权值,而树的中间节点存储的是两个权值较小节点的和。
//初始化队列
Queue* initializeQueue(){
Queue *queue = (Queue*)malloc(sizeof(Queue));
Queue->front = NULL;
Queue->rear = NULL;
return queue;
}
//入队
void enqueue(Queue *queue ,TreeNode *treeNode){
QueueNode *newNode = (QueueNode*)malloc(sizeof(QueueNode));
newNode->treeNode = treeNode;
newNode->next = NULL;
//如果队列为空或者新节点的权值小于队列头结点的权值,则将新节点插入队列头部
If(queue->front = NULL || treeNode->data < queue->front->treeNode->data){
newNode->next=queue->front;
queue->front = newNode;
If(queue->rear = NULL){
Queue->rear == newNode;
}
Return ;
}
//找到合适的位置将新节点插入队列中
QueueNode *current = queue->front; //即工作指针
while(current->next!=NULL&¤t->next->treeNode->data<treeNode->data){
current = current->next;
}
newNode->next = current->next;
current->next= newNode;
If(newNode->next=NULL)
queue->rear = newNode;
}
//出队列
TreeNode* dequeue(Queue *queue){
If(queue->front == NULL){
printf(“Queue is Empty”);
return NULL;
}
QueueNode *temp = queue->front;
TreeNode *treeNode =temp->treeNode;
queue->front=queue->front-next;
if(queue->front == NULL){
queue->rear=NULL;
}
free(temp);
Return treeNode;
}
//创建新的树节点
TreeNode* createTreeNode(int data){
TreeNode *newNode = (TreeNode*)malloc(sizeof(TreeNode));
newNode->data=data;
newNode->lchild = NULL;
newNode->rchild = NULL;
return newNode;
}
//比较函数用于排序
Int compare(const void *a ,const void *a ){
return (*(int*)a-*(int*)b);
}
//构建哈夫曼树
TreeNode* buildHuffmanTree(int frequency[],int n){
//对频率数组进行排序
qsort(frequecny,n,sizeof(int),compare);
Queue *queue = initializeQueue();
//将所有权值作为叶子节点加入队列
for(int i=0;i<n;i++){
enqueue(queue,createTreeNode(frequency[i]));
}
//构建哈夫曼树的过程
while(queue->front!=NULL&&queue->front->next!=NULL){
TreeNode *lchild =dequeue(queue);
TreeNode *rchild =dequeue(queue);
//创建新节点,左右子树分别为权值最小的两个节点
TreeNode *parent = createNode(lchild->data+rchild->data);
parent->lchild=lchild;
parent ->rchild=rchild;
//将新节点加入队列
enqueue(queue,parent);
}
TreeNode *huffmanTree = dequeue(queue);//队列中剩下的节点即为哈夫曼树的根节点
free(queue);
return huffmanTree;
}