⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skyrainreg.cpp

📁 《数据结构》中二叉树的常用算法的练习。包括排序、兄弟-孩子链表的建立
💻 CPP
📖 第 1 页 / 共 5 页
字号:
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 + -