📄 skyrainreg.cpp
字号:
void CSkyRainReg::SetUnvisited(PREGKEY pRoot)
{
if (pRoot)
{
pRoot->Visited = vtUNVISITED;
SetUnvisited(pRoot->SubKey);
SetUnvisited(pRoot->SibKey);
}
}
//---------------------------------------------------------------------------
PREGINFO CSkyRainReg::CreateInfoNode(PSTRTYPE Name)
{ // 创建一个以Name为名称的信息结点 2006.02.19
PREGINFO pTemp = new REGINFO;
pTemp->StringSize = StrLen(Name);
return pTemp;
}
//---------------------------------------------------------------------------
PREGKEY CSkyRainReg:: CreateKeyNode(PREGINFO InfoNode, PSTRTYPE Name)
{ // 创建一个以InfoNode为信息结点、以Name为名称的主键结点 2006.02.19
PREGKEY pTemp = new REGKEY;
pTemp->Info = InfoNode;
StrCopy(pTemp->Name, Name);
return pTemp;
}
//---------------------------------------------------------------------------
PREGVALUE CSkyRainReg::CreateValueNode(PREGINFO InfoNode, PSTRTYPE Name)
{ // 创建一个以InfoNode为信息结点、以Name为名称的键值结点
// 2006.02.19
PREGVALUE pTemp = new REGVALUE;
pTemp->Info = InfoNode;
StrCopy(pTemp->Name, Name);
return pTemp;
}
//---------------------------------------------------------------------------
void CSkyRainReg::CreateNode(PREGKEY &pNode,PREGINFO InfoNode,PSTRTYPE AName)
{ // 创建主键结点Node
pNode = new REGKEY;
pNode->Info = InfoNode;
StrCopy(pNode->Name, AName);
}
//---------------------------------------------------------------------------
void CSkyRainReg::CreateNode(PREGVALUE &Node,PREGINFO InfoNode,PSTRTYPE AName)
{ // 创建键值结点Node
Node = new REGVALUE;
Node->Next = NULL;
Node->Info = InfoNode;
StrCopy(Node->Name, AName);
}
//---------------------------------------------------------------------------
/****************************************************************************
* *
* 函数名称:ReadValueList *
* *
* 实现功能:从文件中读取数据到主键结点ParentKey的键值链表Value中 *
* *
* 参数说明:ParentKey 二叉树中的结点, 键值链表的所有者主键 *
* hFile 已打开的数据文件的句柄 *
* *
* 返 回 值:若读取数据成功返回TRUE,否则返回FALSE *
* *
* 日 期:2006.01.28 -- 2006.03.02 *
* *
****************************************************************************/
bool CSkyRainReg::ReadValueList(PREGKEY ParentKey, HANDLE hFile)
{
// 4.读主键所拥有的键值
PREGVALUE pValue = ParentKey->Value;
PREGINFO InfoNode;
PREGVALUE ValueNode;
PSTRTYPE Name;
DWORD nReadCount=0;
do
{
// 4.1读键值结点信息
InfoNode = new REGINFO;
ReadFile(hFile,InfoNode,sizeof(REGINFO),&nReadCount,NULL);
if (nReadCount < sizeof(REGINFO))
{
delete InfoNode;
break;
}
// 4.2读键值名
Name = new STRTYPE[InfoNode->StringSize+1];
Name[InfoNode->StringSize] = '\0';
ReadFile(hFile,Name,sizeof(STRTYPE)*InfoNode->StringSize,&nReadCount,NULL);
if (nReadCount < sizeof(STRTYPE)*InfoNode->StringSize)
{
delete Name;
delete InfoNode;
break;
}
// 4.3创建一个键值结点
CreateNode(ValueNode, InfoNode, Name);
// 4.4根据读出的键值结点信息中记录键值数据类型的信息,读键值数据
switch(InfoNode->DataType)
{
case dtINT :
ValueNode->Data = new int [InfoNode->DTByteLen];
break;
case dtBOOL :
ValueNode->Data = new bool [InfoNode->DTByteLen];
break;
case dtSTRING :
ValueNode->Data = new STRTYPE[InfoNode->DTByteLen];
break;
case dtDATETIME :
ValueNode->Data = new CDateTime[InfoNode->DTByteLen];
break;
case dtFLOAT :
ValueNode->Data = new float [InfoNode->DTByteLen];
break;
}
ReadFile(hFile, ValueNode->Data,
InfoNode->DTByteSize*InfoNode->DTByteLen,
&nReadCount, NULL);
if (nReadCount < InfoNode->DTByteLen * InfoNode->DTByteSize)
{
delete ValueNode;
break;
}
// 4.5把正确读出键值数据创建的键值结点连接键值链表中
if (!ParentKey->Value)
{
ParentKey->Value = ValueNode;
}
else
{
pValue->Next = ValueNode;
}
pValue = ValueNode;
}while(InfoNode->sFlag == hsnHAVE); // 当前已读出的键值结点有子结点,继续读取
return TRUE;
}
//---------------------------------------------------------------------------
/****************************************************************************
* *
* 函数名称:ReadCreateKeyNode *
* *
* 隶属对象:CSkyRainReg : private *
* *
* 用 法:ReadCreateKeyNode(SkyRain::CKeyNode *&KeyNode, CFile *AFile) *
* *
* 实现功能:从文件AFile中读取主键结点数据,并创建该主键结点为KeyNode。 *
* *
* 参数说明:KeyNode 需要创建的主键结点 *
* AFile 已打开的数据文件 *
* *
* 返 回 值:若成功创建返回TRUE,否则返回FALSE *
* *
* 日 期:2006.02.17 *
* *
****************************************************************************/
bool CSkyRainReg::ReadCreateKeyNode(PREGKEY &KeyNode, HANDLE hFile)
{
//ShowMsg("开始读取主键数据并创建");
// 1.读主键结点信息
DWORD nReadCount = 0;
PREGINFO InfoNode = new REGINFO;
ReadFile(hFile,InfoNode,sizeof(REGINFO),&nReadCount,NULL);
// 读到文件结尾,或读数错误
if (nReadCount < sizeof(REGINFO))
{
delete InfoNode;
return FALSE;
}
// 2.读主键名
PSTRTYPE Key = new STRTYPE[InfoNode->StringSize+1];
Key[InfoNode->StringSize]='\0';
ReadFile(hFile,Key,sizeof(STRTYPE)*InfoNode->StringSize,&nReadCount,NULL);
if(nReadCount < sizeof(STRTYPE) * InfoNode->StringSize)
{
delete Key;
delete InfoNode;
return FALSE;
}
// 3.创建一个主键结点
CreateNode(KeyNode, InfoNode, Key);
// 4.如果该主键结点信息记录中记录有键值结点,则读取KeyNode拥有的键值结点
if (InfoNode->vFlag == hsnHAVE)
{
ReadValueList(KeyNode, hFile);
}
return TRUE;
}
//---------------------------------------------------------------------------
/****************************************************************************
* *
* 函数名称:PreOrderCreateBiTree *
* *
* 实现功能:先序从文件中读取数据并创建二叉树,数据保存的格式参见说明 *
* 采用先根遍历孩子--兄弟二叉链表方法建立二叉树链表结构。 *
* 例如创建如下的二叉树: *
* Root --->■A *
* / *
* / *
* ■B───●b0───●b1 *
* / \ *
* / \ *
* c0●───■C ■F───●f0───●f1 *
* \ *
* \ *
* ■D *
* *
* 第01步: 创建根结点A *
* Root --->■A<---PrevNode *
* *
* 第02步: 根据结点A的信息中sFlag的值判定,如果sFlag=hsnHAVE则读取并创建 *
* 根结点A的孩子结点B,创建B之后移动PrevNode到B。如果sFlag=hsnNO *
* 则执行第04步。 *
* Root --->■A *
* / *
* / *
* PrevNode-->■B *
* *
* 第03步: 根据主键结点B信息中记录键值信息,读取B的键值链表。读取完之后 *
* 重复第02步。 *
* Root --->■A *
* / *
* / *
* PrevNode-->■B───●b0───●b1 *
* *
* Root --->■A *
* / *
* / *
* ■B───●b0───●b1 *
* / *
* / *
* c0●───■C<--PrevNode *
* *
* 第04步: 回溯PrevNode指针。 *
* 回溯的条件为: *
* 条件一:PrevNode指示的结点的兄弟结点指针为空,且PrevNode指示的 *
* 结点的信息中sFlag=hsnNO。 *
* 或条件二:PrevNode指示的结点的兄弟结点指针不为空,且PrevNode指 *
* 示的结点的信息中sFlag=hsnHAVE。 *
* 另外根据实际情况和算法定义,PrevNode指示的结点的兄弟结点指针不 *
* 为空,且PrevNode指示的结点的信息中sFlag=hsnNO,是不存在的。 *
* 综合以上:只有PrevNode指示的结点的兄弟结点指针为空,且PrevNode *
* 指示的结点的信息中 sFlag=hsnHAVE时,回溯结束,在结束的结点处即 *
* 是要插入的位置。 *
* 如第03步插入C之后,C的Info->cFlag = hsnNO,没有子结点,此时回溯 *
* PrevNode=C,C->SibKey==NULL,且C->Info->sFlag=hsnHAVE,再创建的 *
* 结点D即为C的兄弟结点。插入C之后执行第02步。 *
* Root --->■A *
* / *
* / *
* ■B───●b0───●b1 *
* / *
* / *
* c0●───■C *
* \ *
* \ *
* ■D<--PrevNode *
* *
* 第05步: 回溯PrevNode指针插入结点E。 *
* 根据第04步条件回溯PrevNode指针为: *
* Root --->■A *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -