📄 lzcomp.c
字号:
/* TS = none */
/*
** LZCOMP.C
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#include "..\sutkcomp.h"
#ifdef OS2SU
#include <doscalls.h>
#endif
#include "lz.h"
/*
** void LZInitTree(void)
**
** For i = 0 to cbBufMax - 1, rson[i] and lson[i] will be the right and
** left children of node i. These nodes need not be initialized.
** Also, dad[i] is the parent of node i. These are initialized to
** nilND (= N), which stands for 'not used.'
** For i = 0 to 255, rson[cbBufMax + i + 1] is the root of the tree
** for strings that begin with character i. These are initialized
** to nilND. Note there are 256 trees.
*/
void LZInitTree(void)
{
USHORT us;
for (us = 0; us < cbBufMax; us++)
{
rgND[us].ibRingBuf = us;
rgND[us].pNDpar = &nilND;
}
for (us = 0; us < 256; us++)
rgRoot[us].pNDright = &nilND;
}
/*
** void LZDeleteNode(SHORT iND)
**
** Deletes node p from tree.
*/
void LZDeleteNode(SHORT iND)
{
register ND *pNDdel = &rgND[iND];
register ND *pND;
if (pNDdel->pNDpar == &nilND)
return; /* not in tree */
// if the node is a leaf, the insert ND is easy
if (pNDdel->pNDright == &nilND)
pND = pNDdel->pNDleft;
else if (pNDdel->pNDleft == &nilND)
pND = pNDdel->pNDright;
else // node to be deleted is an interior node
{
pND = pNDdel->pNDleft;
if (pND->pNDright != &nilND)
{
do {
pND = pND->pNDright;
} while (pND->pNDright != &nilND);
pND->pNDpar->pNDright = pND->pNDleft;
pND->pNDleft->pNDpar = pND->pNDpar;
pND->pNDleft = pNDdel->pNDleft;
pNDdel->pNDleft->pNDpar = pND;
}
pND->pNDright = pNDdel->pNDright;
pNDdel->pNDright->pNDpar = pND;
}
pND->pNDpar = pNDdel->pNDpar;
// set the rigth/left pointer to parent node to new current
if (pNDdel->pNDpar->pNDright == pNDdel)
pNDdel->pNDpar->pNDright = pND;
else
pNDdel->pNDpar->pNDleft = pND;
pNDdel->pNDpar = &nilND;
}
/*
** Inserts string of length cbStrMax, ringBuf[r..r+cbStrMax-1], into one of the
** trees (rgRoot[*iString]'th tree) and returns the longest-match position
** and length via the global variables iMatchCur and cbMatchCur.
** If cbMatchCur = cbStrMax, then removes the old node in favor of the new
** one, because the old one will be deleted sooner.
**
** There is a one to one relationship with the i'th position in the ringBuf
** and the i'th position in the rgND.
*/
void LZInsertNode(SHORT iString)
{
ND * pND;
ND * pNDNew;
SHORT fComp;
SHORT cbMatchND;
BYTE far * pKey;
pKey = &ringBuf[iString];
pND = &rgRoot[*pKey]; // start with tree index by first char in string
pNDNew = &rgND[iString];
pNDNew->pNDleft = pNDNew->pNDright = &nilND;
cbMatchCur = 0;
goto first;
do {
// Follow the tree down to the leaves depending on the result
// of the last string compare. When you come the a leaf in the
// tree, you are done and insert the node.
if (fComp >= 0)
{
first:
if (pND->pNDright != &nilND)
pND = pND->pNDright;
else
{
pND->pNDright = pNDNew;
pNDNew->pNDpar = pND;
return;
}
}
else
{
if (pND->pNDleft != &nilND)
pND = pND->pNDleft;
else
{
pND->pNDleft = pNDNew;
pNDNew->pNDpar = pND;
return;
}
}
// compare the string at the current node with the string
// that we are looking for.
for (cbMatchND = 1; (USHORT)cbMatchND < cbStrMax; cbMatchND++)
if ((fComp =pKey[cbMatchND]-ringBuf[pND->ibRingBuf+cbMatchND]) != 0)
break;
// if the length of the matched string is greater then the
// current, make the iMatchCur point the pND
if ((USHORT)cbMatchND > cbMatchCur)
{
/* iMatchCur = (ND far *)pND - (ND far *)rgND; */
unsigned long ul = (unsigned long)((BYTE far *)pND);
ul -= (unsigned long)((BYTE far *)rgND);
ul = ul / sizeof(ND);
if (ul > 0x0000FFFF)
printf("Assert - Overflow in iMatchCur assignment!\n");
iMatchCur = (USHORT)ul;
cbMatchCur = (USHORT)cbMatchND;
}
// Search for strings while a less then maxium length string
// is found
} while (cbMatchCur < cbStrMax);
// replace an older ND with the new node in the tree,
// by replacing the current pND with the new node pNDNew
pNDNew->pNDleft = pND->pNDleft;
pND->pNDleft->pNDpar = pNDNew;
pNDNew->pNDright = pND->pNDright;
pND->pNDright->pNDpar = pNDNew;
// insert into left/right side of parent
pNDNew->pNDpar = pND->pNDpar;
if (pND->pNDpar->pNDright == pND)
pND->pNDpar->pNDright = pNDNew;
else
pND->pNDpar->pNDleft = pNDNew;
pND->pNDpar = &nilND; /* remove old node */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -