数据结构与算法基础之哈夫曼编码(C语言)
学习来源:
数据结构与算法基础(青岛大学-王卓)
地址:
https://www.bilibili.com/video/BV1nJ411V7bd?p=22&spm_id_from=pageDriver
背景:
实现视频里老师的伪代码,并不完全一样,但基本雷同。
更新
2021/10/8
第一次发布
代码:
- 栈的实现(作为工具)
Stack.h
#ifndef _STACK_H_
#define _STACK_H_
//Stack object.
typedef struct Stack *Stack;
//Your show function pointer.
typedef void (*Fun_Stack)(void *);
//Get current stack length.
//The "s" is the stack object.
unsigned GetLen_Stack(Stack s);
//Create a new stack.
//This "DataSize" is how much the byte number of your data type.
//This "StackLength" represents the length of your array.
//This function will return the object of stack if it's running successfully
Stack Create_Stack(unsigned DataSize);
//Destroy the stack.
//The "s" is the stack object.
void Destroy_Stack(Stack s);
//Push an element to the stack top.
//The "Elem" is elemet pointer which you need to send.
//The "s" is the stack object.
void Push_Stack(Stack s, void *Elem);
//Show all element's value on console.
//The "s" is the stack object.
//The "f" is your function, it will execute f for stack's len times.
void Show_Stack(Stack s, Fun_Stack f);
//POP a element.
//The "s" is the stack object.
//The "ret" is pop elememt's value.
void POP_Stack(Stack s, void *ret);
//Clear stack of s.
void Clear_Stack(Stack s);
int isEmpty_Stack(Stack s);
#endif
Stack.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Stack.h"
#include "CommonFunc.h"
#define StackBaseLen 20
struct Stack
{
void *ESP;//The stack's top.
void *EBP;//The stack's tail.
void *Data;//Stack memory's address.
unsigned DataSize;//Stack element's type size.
unsigned StackLength;//Stack max length.
};
static int isFull_Stack(Stack s);
static void Expand_Stack(Stack s);
//Expand the stack max length when the elements' amount have out of limit.
static void Expand_Stack(Stack s)
{
NULLPointOut(s, "Expand_Stack", "s");
unsigned len = GetLen_Stack(s);
unsigned DataSize = s->DataSize;
void *Data = s->Data;
unsigned NewStackLength = s->StackLength + StackBaseLen;
void *NewData = malloc(NewStackLength * DataSize);
NULLMallocOut(NewData, "Expand_Stack", "NewData");
void *NewEBP = Index(NewData, (int)NewStackLength, DataSize);
void *NewESP = Index(NewData, (int)(NewStackLength - len), DataSize);
memcpy(NewESP, s->ESP, len * DataSize);
s->StackLength = NewStackLength;
s->Data = NewData;
s->EBP = NewEBP;
s->ESP = NewESP;
free(Data);
return;
}
void Clear_Stack(Stack s)
{
NULLPointOut(s, "Clear_Stack", "s");
s->ESP = s->EBP;
return;
}
void POP_Stack(Stack s, void *ret)
{
NULLPointOut(s, "POP_Stack", "s");
NULLPointOut(ret, "POP_Stack", "ret");
unsigned typeSize = s->DataSize;
if(isEmpty_Stack(s))
{
memset(ret, 0, typeSize);
return;
}
memcpy(ret, s->ESP, typeSize);
s->ESP = PointerInc(s->ESP, typeSize);
return;
}
void Show_Stack(Stack s, Fun_Stack f)
{
NULLPointOut(s, "Show_Stack", "s");
long len = GetLen_Stack(s);
void *tmp = s->ESP;
unsigned typeSize = s->DataSize;
puts("------------------");
printf("length = %ld, DataSize = %u\n", len, typeSize);
long i;
for(i = 0; i < len; i++)
{
f(tmp);
tmp = PointerInc(tmp, typeSize);
}
puts("");
puts("");
return;
}
//Get current stack length.
//The "s" is the stack object.
unsigned GetLen_Stack(Stack s)
{
NULLPointOut(s, "GetLen_Stack", "s");
return (unsigned)PointerSub(s->EBP, s->ESP, s->DataSize);
}
static int isFull_Stack(Stack s)
{
NULLPointOut(s, "isFull_Stack", "s");
//Full return 1 else return 0;
return GetLen_Stack(s) == s->StackLength ? 1 : 0;
}
int isEmpty_Stack(Stack s)
{
NULLPointOut(s, "isEmpty_Stack", "s");
//Empty return 1 else return 0;
return GetLen_Stack(s) == 0 ? 1 : 0;
}
void Push_Stack(Stack s, void *Elem)
{
NULLPointOut(s, "Push_Stack", "s");
NULLPointOut(Elem, "Push_Stack", "Elem");
while(isFull_Stack(s))
{
Expand_Stack(s);
}
s->ESP = PointerDec(s->ESP, s->DataSize);
memcpy(s->ESP, Elem, s->DataSize);
return;
}
Stack Create_Stack(unsigned DataSize)
{
if(DataSize == 0)
{
return NULL;
}
unsigned StackLength = StackBaseLen;
Stack s = (Stack)malloc(sizeof(struct Stack));
NULLMallocOut(s, "Create_Stack", "s");
s->Data = malloc(DataSize * StackLength);
NULLMallocOut(s->Data, "Create_Stack", "Data");
//The stack's tail is memory's higher address.
//The stack's top is memory's lower address.
s->EBP = Index(s->Data, (int)StackLength, DataSize);
s->ESP = Index