?? treeinfo.cpp
字號:
if(pPrev->pPrev == NULL)
{
pNode->pParent->pChild = pNode;
}
else
{
pPrev->pPrev->pNext = pNode;
}
pPrev->pNext = pNext;
pPrev->pPrev = pNode;
}
return TRUE;
}
// 拷貝當前節點(當前節點如有子節點,則包括子節點)。
// 返回:被拷貝的節點地址(重新分配的),成功 非NULL;失敗 NULL
// 注意:各節點是重新NEW出來的,使用時應不應忘記Remove
PTREENODE CTreeInfo::CopyNode( PCTREENODE pcNode )
{
_ASSERTE( pcNode != NULL );
PTREENODE pNew = MallocNode();
if(pNew == NULL)
return NULL;
memcpy(pNew, pcNode, sizeof(TREE_NODE));
pNew->pParent = NULL;
pNew->pChild = NULL;
pNew->pPrev = NULL;
pNew->pNext = NULL;
PTREENODE pRet = NULL;
PTREENODE pPrev = NULL;
for(PCTREENODE pCur = pcNode->pChild; pCur != NULL; pCur = pCur->pNext)
{
pRet = CopyNode(pCur);
if(pRet != NULL)
{
// the first child
if(pCur->pPrev == NULL)
{
pNew->pChild = pRet;
pRet->pParent = pNew;
pPrev = pRet;
}
else
{
// Not the first child
_ASSERTE( pPrev != NULL );
pRet->pParent = pNew;
pRet->pPrev = pPrev;
pPrev->pNext = pRet;
pPrev = pRet;
}
}
else
{
break;
}
}
return pNew;
}
// 將給定的節點孤立出來
// 注意:需要將兄弟節點連接起來
void CTreeInfo::IsolateNode( PTREENODE pNode )
{
PTREENODE pCur = pNode;
PTREENODE pParent = pCur->pParent;
PTREENODE pPrev = pCur->pPrev;
PTREENODE pNext = pCur->pNext;
if(pPrev != NULL)
{
pPrev->pNext = pNext;
}
else
{
if(pParent != NULL)
{
pParent->pChild = pNext;
}
}
if(pNext != NULL)
{
pNext->pPrev = pPrev;
}
pNode->pParent = NULL;
}
// 獲取給定節點的子節點的層數(有幾層子節點),不包含本身。
// 0說明無子節點,1說明有1層子節點,2說明有兩層子節點...
UINT CTreeInfo::GetLevelCount( PCTREENODE pcNode ) const
{
_ASSERTE( pcNode != NULL );
if( pcNode->pChild == NULL )
return 0;
UINT uMaxLevel = 0;
for ( PCTREENODE pCur = pcNode->pChild; pCur != NULL; pCur = pCur->pNext )
{
UINT uLevel = GetLevelCount( pCur );
if ( uLevel > uMaxLevel )
{
uMaxLevel = uLevel;
}
}
return uMaxLevel + 1;
}
// 獲取相對于當前菜單某一層(某一代)所有菜單的數量
// pcNode:當前給定節點, nLevel: 要訪問的層數,子節點的層數為1,孫子節點的層數為2...
// 返回:給定層的菜單的數量
UINT CTreeInfo::GetCountInLevel( PCTREENODE pcNode, int nLevel ) const
{
_ASSERTE( pcNode != NULL && nLevel >= 0 );
if(pcNode->pChild == NULL || nLevel == 0)
{
return 0;
}
UINT uLevelCount = 0;
for ( PCTREENODE pCur = pcNode->pChild; pCur != NULL; pCur = pCur->pNext )
{
if(1 == nLevel)
{
uLevelCount++;
}
else
{
uLevelCount += GetCountInLevel(pCur, nLevel - 1);
}
}
return uLevelCount;
}
// 獲取當前節點,給定層數,給定索引的節點。說明:這些節點的索引順序
// 按照在節點樹中的順序由上到下排列。
// pcNode:給定的節點, nLevel:層數, nIndex:給定層上節點的索引
// 返回:NULL 給定信息無對應的節點, 非NULL 獲取的節點
PTREENODE CTreeInfo::GetNodeInLevel( PCTREENODE pcNode, int nLevel, int nIndex ) const
{
_ASSERTE(pcNode != NULL);
_ASSERTE( nLevel >= 0 && nIndex >= 0 );
return GetLevelInternalUse(pcNode, nLevel, nIndex);
}
PTREENODE CTreeInfo::GetLevelInternalUse(PCTREENODE pcNode, int nLevel, int &nIndex) const
{
_ASSERTE(pcNode != NULL);
if(pcNode->pChild == NULL || nLevel == 0)
return NULL;
PTREENODE pRet = NULL;
for ( PTREENODE pCur = pcNode->pChild; pCur != NULL; pCur = pCur->pNext)
{
if(1 == nLevel)
{
if(0 == nIndex)
return pCur;
else
nIndex--;
}
else
{
pRet = GetLevelInternalUse(pCur, nLevel - 1, nIndex);
if(pRet != NULL)
break;
}
}
return pRet;
}
// 獲取當前給定節點的所有子孫節點的數量(包括本身)
UINT CTreeInfo::GetAllPosteritiesCount( PCTREENODE pcNode ) const
{
_ASSERTE( pcNode != NULL );
if( pcNode->pChild == NULL )
return 1;
UINT uMaxCount = 1;
for( PCTREENODE pCur = pcNode->pChild; pCur != NULL; pCur = pCur->pNext )
{
uMaxCount += GetAllPosteritiesCount( pCur );
}
return uMaxCount;
}
// 給定的節點(lpcNode)是否是lpcParent的子孫節點(包括本身)
BOOL CTreeInfo::IsPosterity(PCTREENODE pcParent, PCTREENODE pcNode) const
{
_ASSERTE(pcParent != NULL);
_ASSERTE(pcNode != NULL);
if( pcParent == pcNode )
return TRUE;
PCTREENODE pChild = pcParent->pChild;
for(; pChild != NULL; pChild = pChild->pNext)
{
if( IsPosterity(pChild, pcNode) )
return TRUE;
}
return FALSE;
}
void CTreeInfo::RemoveNodeInternalUse( PTREENODE pNode )
{
if( NULL == pNode )
return;
PTREENODE pChild = pNode->pChild;
while ( NULL != pChild )
{
PTREENODE pNext = pChild->pNext;
RemoveNode( pChild );
pChild = pNext;
}
delete pNode;
}
// 刪除當前節點(當前節點如有子節點,則包括子節點)
// 注意:需要對上下的指向節點進行處理
void CTreeInfo::RemoveNode( PTREENODE lpNode )
{
if(lpNode != NULL)
{
IsolateNode(lpNode);
RemoveNodeInternalUse(lpNode);
}
}
// 此函數直接調用RemoveNode(PTREENODE lpNode),將根節點作為參數傳入即可。
void CTreeInfo::RemoveAll()
{
if(m_pRoot != NULL)
{
RemoveNode(m_pRoot);
m_pRoot = NULL;
}
}
void CTreeInfo::ZeroNode( PTREENODE pNode )
{
if(pNode != NULL)
{
pNode->pChild = NULL;
pNode->pNext = NULL;
pNode->pParent = NULL;
pNode->pPrev = NULL;
}
}
//////////////////////////////////////////////////////////////////////
// virtual fun 需要在派生類中重新實現
//////////////////////////////////////////////////////////////////////
// 從內存中分配一個新節點,此函數應在派生類中重新實現,以便獲取實際節點。
PTREENODE CTreeInfo::MallocNode( void )
{
return new TREE_NODE;
}
void CTreeInfo::FreeNode( PTREENODE pNode )
{
delete pNode;
}
//////////////////////////////////////////////////////////////////////
// 文件操作(不再提供)
//////////////////////////////////////////////////////////////////////
// 將指定節點及其子孫節點保存到文件,此函數會調用GetNodeSize來獲取節點的
// 大小。
//BOOL CTreeInfo::SaveToFile( PCTREENODE pcNode, FILE * pFILE )
//{
// 此函數應在派生類中實現
// _ASSERTE( 0 );
// return FALSE;
//}
// 從文件中讀取所有節點信息,并返回鏈表中第一個節點的指針,
// 注意此函數會調用MallocNode來分配新節點。
//PTREENODE CTreeInfo::ReadFromFile( FILE * pFILE )
//{
// 此函數應在派生類中實現
// _ASSERTE( 0 );
// return NULL;
//}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -