基于单片机的数据压缩算法的实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include
#include
#define TRUE 1
#define FALSE 0
// 编码的最大位数
#define MAXBITS 50
// 最大的字符数
#define MAXSYMBS MAXBITS
// 树中的最大节点
#define MAXNODES 2 * MAXSYMBS-1
struct CodeType {
int nBits[MAXBITS];
int nStartPos;
};
struct NodeType {
int nFrequency;
int nParent;
int iSLeft;
};
// 队列的插入删除处理
void QueueInsert(int nWhich);
int QueueDelete(void);
// 定义全局变量
struct NodeType node[MAXNODES];
// 队列最初位空
int rootnodes = -1;
void main(void)
{
struct CodeType cd, code[MAXSYMBS];
int i;
int nSymbolsNum;
int nBitCount;
int nNextNode;
int nLeftNode, nRightNode;
int root;
int thisnode;
char symbol, alphabet[MAXSYMBS];
// 清空字符数组
for(i = 0; i < MAXSYMBS; i++)
{
alphabet[i] = ' ';
}
/*// 有多少个字符
printf("Please input char's count\n");
scanf("%d", &nSymbolsNum);
printf("Please input char and frequencies\n");
// 得到数据和每个字符的频率
for(i = 0; i < nSymbolsNum; i++)
{
scanf("%s%d", &symbol, &node[i].nFrequency);
QueueInsert(i);
alphabet[i] = symbol;
}*/
//构造信源数据
nSymbolsNum = 3;
alphabet[0] = 'a';
node[0].nFrequency = 8;
QueueInsert(0);
alphabet[1] = 'b';
node[1].nFrequency = 2;
QueueInsert(1);
alphabet[2] = 'c';
node[2].nFrequency = 5;
QueueInsert(2);
// 形成Huffman树
for(nNextNode = nSymbolsNum;
nNextNode < 2 * nSymbolsNum - 1;
nNextNode ++)
{
nLeftNode = QueueDelete();
nRightNode = QueueDelete();
// 形成新的树,作为子节点
node[nLeftNode].nParent = nNextNode;
node[nRightNode].nParent = nNextNode;
node[nLeftNode].iSLeft = TRUE;
node[nRightNode].iSLeft = FALSE;
// 父节点的频率是两个子节点频率之和
node[nNextNode].nFrequency =
node[nLeftNode].nFrequency + node[nRightNode].nFrequency;
//插入节点
QueueInsert( nNextNode);
}
// 根节点
root = QueueDelete();
// 根据树进行编码
for(i = 0; i < nSymbolsNum; i++)
{
// 搜索的初始点
cd.nStartPos = MAXBITS;
// 对树进行遍历,对内容进行编码
thisnode = i;
while(thisnode != root)
{
--cd.nStartPos;
cd.nBits[cd.nStartPos] = node[thisnode].iSLeft ? 0 : 1;
thisnode = node[thisnode].nParent;
}
// 内容拷贝
for(nBitCount = cd.nStartPos; nBitCount < MAXBITS; nBitCount++)
{
code[i].nBits[nBitCount] = cd.nBits[nBitCount];
}
code[i].nStartPos = cd.nStartPos;
}
for(i = 0; i < nSymbolsNum; i++)
{
printf("\n%c %d ", alphabet[i], node[i].nFrequency);
for(nBitCount = code[i].nStartPos; nBitCount < MAXBITS; nBitCount++)
{
printf("%d", code[i].nBits[nBitCount]);
}
printf("\n");
}
}
// 将节点插入到队列里
void QueueInsert(int nWhich)
{
int thisnode, previous;
// 队列是否为空
if(rootnodes == -1)
{
// 空队列
node[nWhic
h].nParent = -1;
rootnodes = nWhich;
}
else
{
thisnode = rootnodes;
previous = -1;
//搜索大的节点
while((thisnode != -1) &&
(node[thisnode].nFrequency < node[nWhich].nFrequency))
{
previous = thisnode;
thisnode = node[thisnode].nParent;
}
// 连接到第一个大的节点
node[nWhich].nParent = thisnode;
if(previous != -1)
{
// 拷贝
node[previous].nParent = nWhich;
}
else
{
// 插入到开始位置
rootnodes = nWhich;
}
}
}
//从优先队列里去掉第一个结点
int QueueDelete(void)
{
int thisnode = rootnodes;
rootnodes = node[thisnode].nParent;
return thisnode;
}