📄 treeinfo.cpp
字号:
// FileName: TreeInfo.cpp
// Author: Anli.wei
// Date: 2005-2-22
// Comment: 定义树的属性结构,并实现属性结构操作的封装,使用时:
// 1. 应派生CTreeNode类,添加自己需要的属性。
// 2. 派生CTreeInfo类,重新实现MallocNode和ZeroNode两个函数
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TreeInfo.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTreeInfo::CTreeInfo()
{
m_pRoot = NULL;
}
CTreeInfo::~CTreeInfo()
{
if(m_pRoot != NULL)
{
RemoveAll();
}
}
// 在进行操作前,必须首先调用此函数(形成虚拟的根节点),否则其余的操作不会有效。
// 成功,返回TRUE;失败,返回FALSE。
BOOL CTreeInfo::InitRoot()
{
if(m_pRoot == NULL)
{
m_pRoot = MallocNode();
if(m_pRoot == NULL)
{
return FALSE;
}
ZeroNode(m_pRoot);
}
return TRUE;
}
// 获取当前节点的父节点
// pcNode, 当前节点
// 成功 非NULL, 失败或没有 NULL
PTREENODE CTreeInfo::GetParent( PCTREENODE pcNode )const
{
if( pcNode != NULL )
{
return pcNode->pParent;
}
else
{
return NULL;
}
}
void CTreeInfo::SetParent( PTREENODE pCur, PCTREENODE pParent) const
{
_ASSERTE( pCur != NULL);
pCur->pParent = (PTREENODE)pParent;
}
// 获取当前节点的子节点
// pcNode, 给定的节点; nIndex, 给定的节点的第几个子节点,缺省为第一个(从0计起)
// 成功 非NULL; 失败 NULL
PTREENODE CTreeInfo::GetChild( PCTREENODE pcNode, int nIdx /* = 0 */ ) const
{
_ASSERTE( pcNode != NULL );
_ASSERTE( nIdx >= 0 );
if( nIdx >= GetChildCount(pcNode) )
{
// 子节点为空的情况已经考虑到,以下处理时不必再考虑
return NULL;
}
PTREENODE pCur = pcNode->pChild;
// 此时pCur肯定不为NULL,所以不必再次判断
for( int i = 0; i < nIdx; ++i )
{
pCur = pCur->pNext;
}
return pCur;
}
// 置当前节点的子节点
void CTreeInfo::SetChild( PTREENODE pCur, PCTREENODE pChild ) const
{
_ASSERTE( pCur != NULL);
pCur->pChild = (PTREENODE)pChild;
}
// 获取当前节点子节点的数量(不包含孙子节点)
// pcNode, 给定节点
// 返回给定节点的子节点个数 >= 0
int CTreeInfo::GetChildCount( PCTREENODE pcNode ) const
{
_ASSERTE(pcNode != NULL);
int nCount = 0;
for(pcNode = pcNode->pChild; pcNode != NULL; pcNode = pcNode->pNext)
{
nCount++;
}
return nCount;
}
// 获取当前节点的上一个兄弟节点
// 成功 非NULL; 失败或无 NULL
PTREENODE CTreeInfo::GetPrev( PCTREENODE pcNode )const
{
if(pcNode != NULL)
{
return pcNode->pPrev;
}
else
{
return NULL;
}
}
// 置当前节点的上一个兄弟节点
void CTreeInfo::SetPrev( PTREENODE pCur, PCTREENODE pcPrev ) const
{
_ASSERTE( pCur != NULL);
pCur->pPrev = (PTREENODE)pcPrev;
}
// 获取当前节点的下一个兄弟节点
// 成功 非NULL; 失败或无 NULL
PTREENODE CTreeInfo::GetNext( PCTREENODE pcNode ) const
{
if(pcNode != NULL)
{
return pcNode->pNext;
}
else
{
return NULL;
}
}
// 置当前节点的下一个兄弟节点
void CTreeInfo::SetNext( PTREENODE pCur, PCTREENODE pcNext) const
{
_ASSERTE( pCur != NULL);
pCur->pNext = (PTREENODE)pcNext;
}
// 为当前节点添加子节点
// bLast 如果父节点已经有子节点,用此来表示该子节点是作为父节点的最后一个
// 子节点(TRUE),还是作为第一个子节点(FALSE),缺省为TRUE。
// 成功 TRUE; 失败 FALSE
BOOL CTreeInfo::AddChild(PTREENODE pParent, PTREENODE pChild, BOOL bLast /* = TRUE */) const
{
_ASSERTE(pParent != NULL);
_ASSERTE(pChild != NULL);
// 将子节点的连接节点初始化
pChild->pParent = pParent;
// 当前节点(pParent)还没有子节点,此时为它添加第一个子节点
if(pParent->pChild == NULL)
{
pParent->pChild = pChild;
return TRUE;
}
// 当前节点(pParent)已经有子节点,此时以标志bLast来判断是将子节点
// (pChild)作为pParent的最后一个子节点,还是第一个子节点.
if(bLast)
{
PTREENODE pLast = pParent->pChild;
while( pLast->pNext != NULL )
{
pLast = pLast->pNext;
}
pLast->pNext = pChild;
pChild->pPrev = pLast;
}
else
{
PTREENODE pFirst = pParent->pChild;
pParent->pChild = pChild;
pChild->pNext = pFirst;
}
return TRUE;
}
// 以当前选中节点为基准插入兄弟节点
// pBase:基准节点(在菜单中已经存在的);pBrother:被插入的节点;
// bBefore:被插入的节点的位置(基准节点的前面:TRUE或后面:FALSE)
// 返回:成功 TRUE;失败 FALSE
BOOL CTreeInfo::InsertInBrothers(PTREENODE pBase, PTREENODE pBrother, BOOL bBefore /* = TRUE */)
{
_ASSERTE(pBase != NULL);
_ASSERTE(pBrother != NULL);
// 将子节点的连接节点初始化
pBrother->pParent = pBase->pParent;
pBrother->pNext = NULL;
pBrother->pPrev = NULL;
if(bBefore)
{
PTREENODE pOldBefore = pBase->pPrev;
if(pOldBefore != NULL)
{
pOldBefore->pNext = pBrother;
}
else
{
pBase->pParent->pChild = pBrother;
}
pBrother->pPrev = pOldBefore;
pBrother->pNext = pBase;
pBase->pPrev = pBrother;
}
else
{
PTREENODE pOldAfter = pBase->pNext;
pBase->pNext = pBrother;
pBrother->pPrev = pBase;
pBrother->pNext = pOldAfter;
if(pOldAfter != NULL)
{
pOldAfter->pPrev = pBrother;
}
}
return TRUE;
}
// 在兄弟节点中移动当前节点(改变当前节点在兄弟节点中的顺序)
// 当前选中节点,// 移动方向 TRUE 向下;FALSE 向上
// TRUE 成功;FALSE 失败
BOOL CTreeInfo::MoveInBrothers(PTREENODE pNode, BOOL bDown /* = TRUE */)
{
_ASSERTE(pNode != NULL);
PTREENODE pPrev = NULL;
PTREENODE pNext = NULL;
if(bDown)
{
if(pNode->pNext == NULL)
{
// 当前节点无下一个兄弟节点
return FALSE;
}
// 当前节点的上一个兄弟节点(可能为NULL)
pPrev = pNode->pPrev;
// 当前节点的下一个兄弟节点(可能为NULL)
pNext = pNode->pNext;
pNode->pPrev = pNext;
pNode->pNext = pNext->pNext;
if(pNext->pNext != NULL)
{
pNext->pNext->pPrev = pNode;
}
pNext->pNext = pNode;
pNext->pPrev = pPrev;
if(pPrev == NULL)
{
pNode->pParent->pChild = pNext;
}
else
{
pPrev->pNext = pNext;
}
}
else
{
if(pNode->pPrev == NULL)
{
// 当前节点无上一个兄弟节点
return FALSE;
}
pPrev = pNode->pPrev;
pNext = pNode->pNext;
// 当前节点的上一个兄弟节点(可能为NULL)
pNode->pPrev = pPrev->pPrev;
// 当前节点的下一个兄弟节点(可能为NULL)
pNode->pNext = pPrev;
if(pNext != NULL)
{
pNext->pPrev = pPrev;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -