sdfsd

// Tree.h: interface for the CTree class.
//
//

#if !defined(AFX_TREE_H__35796AC2_439A_4B70_943C_D75B3D70417F__INCLUDED_)
#define AFX_TREE_H__35796AC2_439A_4B70_943C_D75B3D70417F__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
 
typedef struct tree_node_ {  
public:  
    tree_node_ *parent;  
    tree_node_ *first_child, *last_child;  
    tree_node_ *prev_sibling, *next_sibling;  
    int data;  
}TreeNode,*PTREENODE;

class CTree 
{
public:
 CTree();
 CTree(int i);
 virtual ~CTree();
public:
 void Init();
 void Free();
 void FreeOne(PTREENODE ptreeNode);
 PTREENODE Search(int i);                     // 查找数据域为值i的节点

 // 查找当前节点或当前节点右兄弟的最左孩子(即下层开始节点),若都不存在最左孩子,则返回空
 PTREENODE FindFirstChild(const PTREENODE treeNodeFather);  
 // 恢复节点所在层的初始连接属性。pptreeNode为该层首节点
 void RecoverTreeNode(PTREENODE *pptreeNode);
 // 判断两节点是否为左右兄弟关系
 BOOL IsInNextSiblingOrder(PTREENODE pFirstTreeNode, PTREENODE pSecondTreeNode);
public:
 static PTREENODE BuildTreeNode(TreeNode *parent,TreeNode *first_child,TreeNode *last_child,
  TreeNode *prev_sibling, TreeNode *next_sibling, int data);

private:
 PTREENODE m_ptree;                // 存储树
 PTREENODE m_ptreeNodeFather;      // 层次遍历时当前层的开始节点
 PTREENODE m_ptreeNodeFirstChild;  // 层次遍历时下一层的开始节点
};

#endif // !defined(AFX_TREE_H__35796AC2_439A_4B70_943C_D75B3D70417F__INCLUDED_)

 

// Tree.cpp: implementation of the CTree class.
//
//

#include "stdafx.h"
#include "TreeSearch.h"
#include "Tree.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
// Construction/Destruction
//

void FreeTreeNode(void *lpvoid)
{
 if(lpvoid)
 {
  free(lpvoid);
 }
 lpvoid = NULL;
}

CTree::CTree()
{
//  m_ptree = (PTREENODE)malloc(sizeof(TreeNode));
//  m_ptreeNodeFather = (PTREENODE)malloc(sizeof(TreeNode));
//  m_ptreeNodeFirstChild = (PTREENODE)malloc(sizeof(TreeNode));
 m_ptree = NULL;
 m_ptreeNodeFather = NULL;
 m_ptreeNodeFirstChild = NULL;
}
CTree::CTree(int i)
{
//  m_ptree = (PTREENODE)malloc(sizeof(TreeNode));
//  m_ptreeNodeFather = (PTREENODE)malloc(sizeof(TreeNode));
//  m_ptreeNodeFirstChild = (PTREENODE)malloc(sizeof(TreeNode));
 m_ptree = BuildTreeNode(NULL,NULL,NULL,NULL,NULL,i);
 m_ptreeNodeFather = m_ptree;
 m_ptreeNodeFirstChild = FindFirstChild(m_ptreeNodeFather);
}
CTree::~CTree()
{
//  free(m_ptreeNodeFather);
//  free(m_ptreeNodeFirstChild);
 Free();
}

void CTree::Init()
{

 // 构造如下树
 //         0
 //        /  /
 //       1    2
 //      / /  / /
 //     3  4 5  6
 //        |   / /
 //        7   8  9
 //       / /   
 //      10 11    
 PTREENODE ptreeNodeFirstChild = BuildTreeNode(m_ptree,NULL,NULL,NULL,NULL,1);
 m_ptree->first_child = ptreeNodeFirstChild;
 PTREENODE ptreeNodeLastChild = BuildTreeNode(m_ptree,NULL,NULL,ptreeNodeFirstChild,NULL,2);
 m_ptree->last_child = ptreeNodeLastChild;
 ptreeNodeFirstChild->next_sibling = ptreeNodeLastChild;

 PTREENODE ptreeNodeGrandChild = BuildTreeNode(ptreeNodeFirstChild,NULL,NULL,NULL,NULL,3);
 ptreeNodeFirstChild->first_child = ptreeNodeGrandChild;
 PTREENODE ptreeNodeGrandChild2 = BuildTreeNode(ptreeNodeFirstChild,NULL,NULL,ptreeNodeGrandChild,NULL,4);
 ptreeNodeFirstChild->last_child = ptreeNodeGrandChild2;
 ptreeNodeGrandChild->next_sibling = ptreeNodeGrandChild2;

 PTREENODE ptreeNodeGrandChild3 = BuildTreeNode(ptreeNodeLastChild,NULL,NULL,NULL,NULL,5);
 ptreeNodeLastChild->first_child = ptreeNodeGrandChild3;
 PTREENODE ptreeNodeGrandChild4 = BuildTreeNode(ptreeNodeLastChild,NULL,NULL,ptreeNodeGrandChild3,NULL,6);
 ptreeNodeLastChild->last_child = ptreeNodeGrandChild4;
 ptreeNodeGrandChild3->next_sibling = ptreeNodeGrandChild4;

 PTREENODE ptreeNodeGrandChild7 = BuildTreeNode(ptreeNodeGrandChild2,NULL,NULL,NULL,NULL,7);
 ptreeNodeGrandChild2->first_child = ptreeNodeGrandChild7;
 ptreeNodeGrandChild2->last_child = ptreeNodeGrandChild7;


 PTREENODE ptreeNodeGrandChild5 = BuildTreeNode(ptreeNodeGrandChild4,NULL,NULL,NULL,NULL,8);
 ptreeNodeGrandChild4->first_child = ptreeNodeGrandChild5;
 PTREENODE ptreeNodeGrandChild6 = BuildTreeNode(ptreeNodeGrandChild4,NULL,NULL,ptreeNodeGrandChild5,NULL,9);
 ptreeNodeGrandChild4->last_child = ptreeNodeGrandChild6;
 ptreeNodeGrandChild5->next_sibling = ptreeNodeGrandChild6;

 PTREENODE ptreeNodeGrandChild8 = BuildTreeNode(ptreeNodeGrandChild7,NULL,NULL,NULL,NULL,10);
 ptreeNodeGrandChild7->first_child = ptreeNodeGrandChild8;
 PTREENODE ptreeNodeGrandChild9 = BuildTreeNode(ptreeNodeGrandChild7,NULL,NULL,ptreeNodeGrandChild8,NULL,11);
 ptreeNodeGrandChild7->last_child = ptreeNodeGrandChild9;
 ptreeNodeGrandChild8->next_sibling = ptreeNodeGrandChild9;

 m_ptreeNodeFather = m_ptree;
 m_ptreeNodeFirstChild= FindFirstChild(m_ptreeNodeFather);
}

PTREENODE CTree::Search( int i )
{
 
 PTREENODE pTarget = NULL;          //用于存储目标树节点
 PTREENODE ptreeNode = NULL;        //循环控制变量
 
 // 指向下层首节点的最右相连兄弟(即同一父节点的最右孩子)
 // 用于使其与父节点的兄弟节点下的下一最左孩子单向右连通(当遍历孩子那层节点完后进行还原)
 // 比如使下边树节点2 的最右孩子5 的右兄弟(本为空)指向6,
 // (还原条件:当下层扫描进行完5后,判断5->next_sibling->prev_sibling 是否为本身,否则把5->next_sibling置空)
 //         1
 //        /  /
 //       2    3
 //      / /  / /
 //     4  5 6  7
 PTREENODE ptreeNodeChild = NULL;      
 
 //以m_ptreeNodeFather为根节点循环遍历每层
 do
 {
  ptreeNode = m_ptreeNodeFather;
  
  // 若下层首节点非空,则把其指向下层首节点的最右相连兄弟
  // 由于每次获取前,m_ptreeNodeFather所在层必定已经
  //   ptreeNodeChild = FindFirstChild(m_ptreeNodeFather);
  //   if (NULL != ptreeNodeChild)
  //    {
  //     ptreeNodeChild = ptreeNodeChild->parent->last_child;
  //    }
  ptreeNodeChild = NULL;
  if (NULL != m_ptreeNodeFirstChild)
  {
   ptreeNodeChild = m_ptreeNodeFirstChild->parent->last_child;
  }
  
  // 循环遍历当前层
  while (NULL != ptreeNode)
  {
   if (ptreeNode->data == 1000)
   {
    pTarget = ptreeNode;
    break;
   }
   printf("%d  ", ptreeNode->data);
   char a[10];
   itoa(ptreeNode->data,a,10);
   CString s;
   s.Format(_T("%s"),a);
   OutputDebugString(s);
   ptreeNode = ptreeNode->next_sibling;
   if (NULL != ptreeNode && NULL != ptreeNode->first_child)   //若节点存在孩子,则使其孩子节点左边相邻节点(未连通,如上图节点5)右向单连通
   {
    // 下边if语句为避免以下情况发生:ptreeNodeChild = 7,此时ptreeNode=3,错误地将7->next_sibling指向6
    //         1
    //        /  /
    //       2    3
    //           / /
    //          6  7
    if (IsInNextSiblingOrder(ptreeNodeChild->parent,ptreeNode))
    {
     //由上边if语句条件成立可知ptreeNodeChild必定非空。
     ptreeNodeChild->next_sibling = ptreeNode->first_child; // 置节点右向单连通
     ptreeNodeChild = ptreeNodeChild->parent->last_child;   // 更新值
    }
   }
  }
  
  // 找到该节点,则返回
  if (NULL != pTarget)
  {
   RecoverTreeNode(&m_ptreeNodeFather);                   // 还原当前遍历层
   RecoverTreeNode(&m_ptreeNodeFirstChild);                   // 还原子节点层
   break;
  }
  
  RecoverTreeNode(&m_ptreeNodeFather);                   // 还原当前遍历层
  m_ptreeNodeFather = m_ptreeNodeFirstChild;                // 把当前层首节点指向下层首节点
  m_ptreeNodeFirstChild = FindFirstChild(m_ptreeNodeFather);
 }while (NULL != m_ptreeNodeFather);
 
 
 m_ptreeNodeFather = m_ptree;
 m_ptreeNodeFirstChild = FindFirstChild(m_ptreeNodeFather);


   return pTarget;
}

PTREENODE CTree::FindFirstChild( const PTREENODE treeNodeFather )
{
 PTREENODE ptreeNodeFirstChild = treeNodeFather;
 if (NULL != ptreeNodeFirstChild)        // 节点本身为空的情况下返回NULL
 {
  while ((NULL == ptreeNodeFirstChild->first_child) && (NULL != ptreeNodeFirstChild->next_sibling))
  {
   ptreeNodeFirstChild = ptreeNodeFirstChild->next_sibling;
  }
  return ptreeNodeFirstChild->first_child;
 }
 else
  return NULL;
 
}

PTREENODE CTree::BuildTreeNode( TreeNode *parent,TreeNode *first_child,TreeNode *last_child,
         TreeNode *prev_sibling, TreeNode *next_sibling, int data )
{
 PTREENODE ptreeNode = (PTREENODE)malloc(sizeof(TreeNode));
//  ptreeNode->parent = (PTREENODE)malloc(sizeof(TreeNode));
 ptreeNode->parent = parent;
//  ptreeNode->first_child = (PTREENODE)malloc(sizeof(TreeNode));
 ptreeNode->first_child = first_child;
//  ptreeNode->last_child = (PTREENODE)malloc(sizeof(TreeNode));
 ptreeNode->last_child = last_child;
//  ptreeNode->next_sibling = (PTREENODE)malloc(sizeof(TreeNode));
 ptreeNode->next_sibling = next_sibling;
//  ptreeNode->prev_sibling = (PTREENODE)malloc(sizeof(TreeNode));
 ptreeNode->prev_sibling = prev_sibling;
 ptreeNode->data = data;
 return ptreeNode;
}

// 若当前节点的下一兄弟节点的左兄弟节点不为当前节点(或者为空),则把当前节点的下一兄弟节点置空。
void CTree::RecoverTreeNode( PTREENODE *pptreeNode )
{
 
 if (NULL != pptreeNode)
 {
  PTREENODE ptreeNode= *pptreeNode;
  PTREENODE pTemp = NULL;
  while (NULL != ptreeNode)
  {
   if (NULL != ptreeNode->next_sibling)
   {
    if (NULL == ptreeNode->next_sibling->prev_sibling)      // or ptreeNode != ptreeNode->next_sibling->prev_sibling
    {
     pTemp = ptreeNode->next_sibling;
     ptreeNode->next_sibling = NULL;
     // ptreeNode = pTemp;
     //break;
    }
   }

   if (NULL != pTemp)
   {
    ptreeNode = pTemp;
    pTemp = NULL;
   }
   else 
   {
    ptreeNode = ptreeNode->next_sibling;
   }
  }
 }
}

void CTree::Free()
{
 
 
 PTREENODE pTarget = NULL;          //用于存储目标树节点
 PTREENODE ptreeNode = NULL;        //循环控制变量
 
 // 指向下层首节点的最右相连兄弟(即同一父节点的最右孩子)
 // 用于使其与父节点的兄弟节点下的下一最左孩子单向右连通(当遍历孩子那层节点完后进行还原)
 // 比如使下边树节点2 的最右孩子5 的右兄弟(本为空)指向6,
 // (还原条件:当下层扫描进行完5后,判断5->next_sibling->prev_sibling 是否为本身,否则把5->next_sibling置空)
 //         1
 //        /  /
 //       2    3
 //      / /  / /
 //     4  5 6  7
 PTREENODE ptreeNodeChild = NULL;      
 
 //以m_ptreeNodeFather为根节点循环遍历每层
 do
 {
  ptreeNode = m_ptreeNodeFather;
  
  // 若下层首节点非空,则把其指向下层首节点的最右相连兄弟
  // 由于每次获取前,m_ptreeNodeFather所在层必定已经
  //   ptreeNodeChild = FindFirstChild(m_ptreeNodeFather);
  //   if (NULL != ptreeNodeChild)
  //    {
  //     ptreeNodeChild = ptreeNodeChild->parent->last_child;
  //    }
  ptreeNodeChild = NULL;
  if (NULL != m_ptreeNodeFirstChild)
  {
   ptreeNodeChild = m_ptreeNodeFirstChild->parent->last_child;
  }
  
  // 循环遍历当前层
  while (NULL != ptreeNode)
  {
   pTarget = ptreeNode;
   printf("%d  ", ptreeNode->data);
   char a[10];
   itoa(ptreeNode->data,a,10);
   CString s;
   s.Format(_T("%s"),a);
   OutputDebugString(s);
   ptreeNode = ptreeNode->next_sibling;
   if (NULL != ptreeNode && NULL != ptreeNode->first_child)   //若节点存在孩子,则使其孩子节点左边相邻节点(未连通,如上图节点5)右向单连通
   {
    // 下边if语句为避免以下情况发生:ptreeNodeChild = 7,此时ptreeNode=3,错误地将7->next_sibling指向6
    //         1
    //        /  /
    //       2    3
    //           / /
    //          6  7
    if (IsInNextSiblingOrder(ptreeNodeChild->parent,ptreeNode))
    {
     //由上边if语句条件成立可知ptreeNodeChild必定非空。
     ptreeNodeChild->next_sibling = ptreeNode->first_child; // 置节点右向单连通
     ptreeNodeChild = ptreeNodeChild->parent->last_child;   // 更新值
    }
   }
  }
  
  //   // 找到该节点,则返回
  //   if (NULL != pTarget)
  //   {
  //    RecoverTreeNode(&m_ptreeNodeFather);                   // 还原当前遍历层
  //    RecoverTreeNode(&m_ptreeNodeFirstChild);                   // 还原子节点层
  //    break;
  //   }
  
  //RecoverTreeNode(&m_ptreeNodeFather);                   // 还原当前遍历层
  FreeOne(m_ptreeNodeFather);
  m_ptreeNodeFather = m_ptreeNodeFirstChild;                // 把当前层首节点指向下层首节点
  m_ptreeNodeFirstChild = FindFirstChild(m_ptreeNodeFather);
 }while (NULL != m_ptreeNodeFather);
 
 
 m_ptreeNodeFather = m_ptree;
 m_ptreeNodeFirstChild = FindFirstChild(m_ptreeNodeFather);
}

BOOL CTree::IsInNextSiblingOrder( PTREENODE pFirstTreeNode, PTREENODE pSecondTreeNode )
{
 BOOL bResult = FALSE;
 if (pFirstTreeNode && pSecondTreeNode)
 {
  PTREENODE pTemp = pFirstTreeNode;
  while (NULL != pTemp)
  {
   pTemp = pTemp->next_sibling;
   if (pTemp == pSecondTreeNode)
   {
    bResult = TRUE;
   }
  }
 }
 return bResult;
}

void CTree::FreeOne( PTREENODE ptreeNode )
{
 if (NULL != ptreeNode)
 {
  PTREENODE pTemp = NULL;
  while (NULL != ptreeNode)
  {
   pTemp = ptreeNode->next_sibling;
   FreeTreeNode(ptreeNode);
   ptreeNode = pTemp;
  }
 }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值