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

📄 treeinfo.cpp

📁 Resource editor base speadrum Chinese mobile
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -