登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Gamebaby Rock Sun的博客

我只知道一件事情,就是我一无所知。

 
 
 

日志

 
 
关于我

曾经拥有的,不要忘记, 已经得到的,更要珍惜, 属于自己的,不要放弃, 已经失去的,留着回忆, 想要得到的,必须努力, 但最重要的,是好好爱惜自己!

我实现的B+树C++模版类(V0.50)  

2008-04-06 22:00:39|  分类: VC/VC++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

       下面是我实现的B+树C++模版类,利用了windows中的一些特性,关于B+树的算法我不再赘述,大家自己搜索一下,满网络都是,此处的实现是一个非常好用的模版版本。可以免费用于任何用途,在版本升级或发生变动后,本人将不通知任何使用者,但是如果需要技术支持、升级服务或培训服务的可以与本人联系,QQ 41750362。

       注意这个地方是0.5版,可以使用但是不很方便,封装还不是很好,本人正在紧张制作1.0版中,有需要的朋友请留言,或关注我的blog,本人在编写完1.0版后即刻发布在这里,供大家使用。

//B树
#include "GRSPublicDef.h"
#pragma once

//==========================================================
//TRank 表示每个节点中的阶数,则节点中的Key数目是2*TRank
//指向下级的指针数目是 2*TRank + 1,同时Key和Data是一对一的
//要求Key类型必须有 > 运算符
//实际使用中最好为TKey和TData类型重载 = 运算符
//==========================================================
template <class TKey,class TData,INT TRank>
class CGRSBTreeNode
{
public:
 INT m_nCnt;    //当前节点中的Key个数
 TKey  m_Key [2 * TRank]; //Key数组
 TData m_Data[2 * TRank];    //Data数组

 CGRSBTreeNode<TKey,TData,TRank>* m_pChild[ 2 * TRank + 1 ]; //指向孩子的指针数组
public:
 CGRSBTreeNode()
  :m_nCnt(0)
 {
  ::ZeroMemory(m_Key, 2 * TRank * sizeof(TKey));
  ::ZeroMemory(m_Data,2 * TRank * sizeof(TData));
  ::ZeroMemory(m_pChild,( 2 * TRank + 1) * sizeof(CGRSBTreeNode<TKey,TData,TRank>*));
 }
};


template <class TKey,class TData,INT TRank = 10>
class CGRSBTree
{
protected:
 CGRSBTreeNode<TKey,TData,TRank>* m_pRoot; //树根节点
 INT  m_iHeight;        //树高度
 INT m_nKeyCnt;        //键总数
 INT m_nNodeCnt;       //节点总数
protected:
 INT m_nSearchIndex;       // 查找时找到的键在节点中的位置

 TData m_InsData;        // 与要插的键相对应的值
 TKey m_InsKey;        /// 要插入的键

 INT  m_iAccessLevel;       // 当前访问的节点所处的高度
 CGRSBTreeNode<TKey,TData,TRank>* m_pNewNode; // 在节点分割的时候指向新建的节点
 
 BOOL m_bFlag;         // 节点增减标志
public:
 CGRSBTree()
  :m_iHeight(0)
  ,m_nKeyCnt(0)
  ,m_nNodeCnt(0)
  ,m_nSearchIndex(0)
  ,m_iAccessLevel(0)
  ,m_pNewNode(NULL)
  ,m_bFlag(FALSE)
 {
  //申请一个0节点的树根
  m_pRoot = NULL;
 }

 virtual ~CGRSBTree()
 {
 }

protected:
 void Insert(CGRSBTreeNode<TKey,TData,TRank>*& pNode,const TKey& Key,const TData& Data)
 {
  INT i = 0;
  INT j = 0;
  INT k = 0;

  m_iAccessLevel --;

  if ( m_iAccessLevel < 0 )
  {
   m_pNewNode = NULL;
   m_InsKey = Key;
   m_InsData = Data;
   m_nKeyCnt ++;
   m_bFlag = TRUE;
   //pNode = NewNode(pNode,Key,Data);
   return;
  }


  for(i = 0, j = pNode->m_nCnt - 1;
   i < j;
   k= ( j + i) / 2, ( Key > pNode-> m_Key[k])?( i = k + 1 ):( j = k ));

  if ( Key == pNode-> m_Key[ i ] )
  {
   Error(1,Key); /* 键已经在树中 */
   m_bFlag = FALSE;
   return;
  }

  if ( Key > pNode-> m_Key[ i ] )
  {/* i == pNode->m_nCnt - 1 时有可能出现 */
   i ++;
  }

  //向孩子节点插入
  Insert( pNode -> m_pChild[ i ] , Key, Data );

  if ( FALSE == m_bFlag )
  {
   return;
  }

  /* 有新键要插入到当前节点中 */
  if ( pNode->m_nCnt < 2 * TRank )
  {/* 当前节点未满 */
   InsertAt( pNode, i ,Key,Data); /* 把键值+子树对插入当前节点中 */
   m_bFlag = FALSE; /* 指示上层节点没有需要插入的键值+子树,插入过程结束 */
  }
  else
  {/* 当前节点已满,则分割这个页面并把键值+子树对插入当前节点中 */
   SplitNode(pNode, i); /* 继续指示上层节点把返回的键值+子树插入其中 */
  }
 }

 /*
 * 把一个键和对应的右子树插入一个节点中
 */
 void InsertAt(CGRSBTreeNode<TKey,TData,TRank>* pNode, INT nIndex,const TKey& Key,const TData& Data)
 {
  int i = 0;
  /* 把所有大于要插入的键值的键和对应的右子树右移 */
  for(i = pNode->m_nCnt; i > nIndex; i--)
  {
   pNode-> m_Key[ i ]  = pNode-> m_Key[i-1];
   pNode-> m_Data[ i ]  = pNode-> m_Data[i-1];
   pNode-> m_pChild[i+1] = pNode-> m_pChild[ i ];
  }

  /* 插入键和右子树 */
  pNode-> m_Key[ i ]  = Key;
  pNode-> m_Data[ i ]  = Data;
  pNode-> m_pChild[ i + 1 ] = m_pNewNode;
  pNode-> m_nCnt ++;
 }

 /*
 * 前件是要插入一个键和对应的右子树,并且本节点已经满
 * 导致分割这个节点,插入键和对应的右子树,
 * 并向上层返回一个要插入键和对应的右子树
 */
 void SplitNode( CGRSBTreeNode<TKey,TData,TRank>*& pNode, INT nIndex )
 {    
  INT i = 0;
  INT j = 0;
  CGRSBTreeNode<TKey,TData,TRank>* pTmpNode = NULL;
  TKey tmpKey;
  TData tmpData;
  /* 建立新节点 */
  pTmpNode = new CGRSBTreeNode<TKey,TData,TRank>();
  /*
  *   +---+--------+-----------+---------+--------+---------+
  *   | 0 | ...... |  TRank    | TRank+1 | ...... |2*TRank-1|
  *   +---+--------+-----------+---------+--------+---------+
  *   |<-      TRank+1       ->|<-        TRank-1         ->|  
  */

  if ( nIndex > TRank )
  {//要插入当前节点的右半部分
   //把从 2*TRank-1 到 TRank+1 的 TRank-1 个键值+子树对转移到新节点中,
   //并且为要插入的键值+子树空出位置
   for( i = 2 * TRank - 1, j = TRank - 1; i >= nIndex; i --,j --)
   {
    pTmpNode-> m_Key[j]    = pNode-> m_Key[ i ];
    pTmpNode-> m_Data[j]   = pNode-> m_Data[ i ];
    pTmpNode-> m_pChild[ j + 1 ] = pNode-> m_pChild[i + 1];
   }

   for(i = nIndex - 1, j = nIndex - TRank - 2; j >= 0; i--,j--)
   {
    pTmpNode-> m_Key[j]    = pNode-> m_Key[ i ];
    pTmpNode-> m_Data[j]   = pNode-> m_Data[ i ];
    pTmpNode-> m_pChild[ j + 1 ] = pNode-> m_pChild[i + 1];
   }

   //把节点的最右子树转移成新节点的最左子树
   pTmpNode-> m_pChild[0] = pNode-> m_pChild[ TRank + 1 ];

   //在新节点中插入键和右子树
   pTmpNode-> m_Key[ nIndex - TRank - 1] = m_InsKey;
   pTmpNode-> m_Data[ nIndex - TRank - 1] = m_InsData;
   pTmpNode-> m_pChild[ nIndex - TRank ] = m_pNewNode;

   //设置要插入上层节点的键和值
   m_InsKey = pNode-> m_Key[TRank];
   m_InsData = pNode-> m_Data[TRank];

   //tmpKey  = pNode->m_Key[TRank];
   //tmpData = pNode->m_Data[TRank];
  }
  else
  { /* nIndex <= TRank */
   /* 把从 2*TRank-1 到 TRank 的 TRank 个键值+子树对转移到新节点中 */
   for( i = 2 * TRank - 1,j = TRank - 1; j >= 0; i--,j--)
   {
    pTmpNode-> m_Key[j]   = pNode-> m_Key[ i ];
    pTmpNode-> m_Data[j]  = pNode-> m_Data[ i ];
    pTmpNode-> m_pChild[j + 1] = pNode-> m_pChild[ i + 1 ];
   }
   
   if (nIndex == TRank)
   {
    pTmpNode-> m_pChild[0] = m_pNewNode;
   }
   else
   { /* (nIndex<TRank) 要插入当前节点的左半部分 */
    /* 把节点当前的最右子树转移成新节点的最左子树 */
    pTmpNode-> m_pChild[0] = pNode-> m_pChild[ TRank ];
    /* 保存要插入上层节点的键和值 */
    tmpKey = pNode-> m_Key[ TRank - 1];
    tmpData = pNode-> m_Data[ TRank - 1];

    /* 把所有大于要插入的键值的键和对应的右子树右移 */
    for(i = TRank - 1; i > nIndex; i --)
    {
     pNode-> m_Key[ i ]   = pNode-> m_Key[i-1];
     pNode-> m_Data[ i ]   = pNode-> m_Data[i - 1];
     pNode-> m_pChild[ i + 1 ] = pNode-> m_pChild[ i ];
    }
    
    pNode-> m_Key[nIndex]  = m_InsKey;
    pNode-> m_Data[nIndex]  = m_InsData;

    pNode-> m_pChild[nIndex+1] = m_pNewNode;
    
    m_InsKey = tmpKey;
    m_InsData = tmpData;
   }
  }

  pNode->m_nCnt = TRank;
  pTmpNode->m_nCnt= TRank;
  m_pNewNode  = pTmpNode;
  m_nNodeCnt ++;

  //pNode = NewNode(pNode,tmpKey,tmpData);
 }


 void Remove( CGRSBTreeNode<TKey,TData,TRank>* pNode,const TKey& Key,TData& Data)
 {
  INT i = 0;
  INT j = 0;
  INT k = 0;
  CGRSBTreeNode<TKey,TData,TRank>* pLeft = NULL;
  CGRSBTreeNode<TKey,TData,TRank>* pRight = NULL;
  INT nTmpLevel = 0;

  m_iAccessLevel -- ;

  if ( m_iAccessLevel < 0 )
  {
   Error(0,Key); /* 在整个树中未找到要删除的键 */
   m_bFlag = FALSE;
   return;
  }

  for(i=0, j = pNode->m_nCnt - 1;
   i < j;
   k=( j + i ) / 2, ( Key > pNode-> m_Key[k] ) ? (i = k + 1):( j = k ));

  if ( Key == pNode-> m_Key[ i ] )
  { /* 找到要删除的键 */
   Data = pNode-> m_Data[ i ];

   if (m_iAccessLevel == 0)
   { 
    DelFromNode(pNode,i);
   
    m_nKeyCnt -- ;
    m_bFlag = TRUE;
    return;
   }
   else
   { /* 这个键位于非叶节点 */
    nTmpLevel = m_iAccessLevel - 1;

    /* 找到前驱节点 */
    pRight = pNode-> m_pChild[ i ];
    
    while (nTmpLevel > 0) 
    {
     pRight = pRight->m_pChild[pRight->m_nCnt];
     nTmpLevel--;
    }

    pNode-> m_Key[ i ]  = pRight-> m_Key[pRight->m_nCnt-1];
    pNode-> m_Data[ i ]  = pRight-> m_Data[pRight->m_nCnt-1];
    pRight-> m_Data[pRight->m_nCnt-1] = NULL;
    Key = pRight-> m_Key[ pRight->m_nCnt - 1 ];
   }
  }
  else if (Key > pNode-> m_Key[ i ])
  {/* i == pNode->m_nCnt-1 时有可能出现 */
   i++;         
  }

  Remove( Key , pNode-> m_pChild[ i ] );

  /* 调整平衡 */
  if ( FALSE == m_bFlag )
  {
   return;
  }

  if (pNode-> m_pChild[ i ]->m_nCnt < TRank)
  {
   if (i == pNode->m_nCnt)
   {/* 在最右子树中发生了删除 */
    i--; /* 调整最右键的左右子树平衡 */
   }

   pLeft = pNode-> m_pChild [ i ];
   pRight = pNode-> m_pChild[i+1];

   if (pRight->m_nCnt > TRank)
   {
    MoveLeftNode(pNode,i);
   }
   else if(pLeft->m_nCnt > TRank)
   {
    MoveRightNode(pNode,i);
   }
   else
   {
    JoinNode(pNode,i);
    /* 继续指示上层节点本子树的键数量减少 */
    return;
   }
   
   m_bFlag = FALSE;
   /* 指示上层节点本子树的键数量没有减少,删除过程结束 */
  }
 }

 /*
 * 合并一个节点的某个键对应的两个子树
 */
 void JoinNode(CGRSBTreeNode<TKey,TData,TRank>* pNode, INT nIndex)
 {
  CGRSBTreeNode<TKey,TData,TRank>* pLeft = NULL;
  CGRSBTreeNode<TKey,TData,TRank>* pRight = NULL;
  INT i = 0;
  INT j = 0;

  pLeft = pNode-> m_pChild[nIndex];
  pRight = pNode-> m_pChild[nIndex + 1];

  /* 把这个键下移到它的左子树 */
  pLeft-> m_Key[pLeft->m_nCnt] = pNode-> m_Key[nIndex];
  pLeft-> m_Data[pLeft->m_nCnt] = pNode-> m_Data[nIndex];

  /* 把右子树中的所有键值和子树转移到左子树 */
  for (j=pRight->m_nCnt-1,i=pLeft->m_nCnt+pRight->m_nCnt; j >= 0 ; j--,i--)
  {
   pLeft-> m_Key[ i ]  = pRight-> m_Key[j];
   pLeft-> m_Data[ i ]  = pRight-> m_Data[j];
   pLeft-> m_pChild[ i ] = pRight-> m_pChild[j];
  }

  pLeft-> m_pChild[ pLeft->m_nCnt + pRight->m_nCnt + 1 ] = pRight-> m_pChild[ pRight->m_nCnt ];
  pLeft->m_nCnt += pRight->m_nCnt + 1;
  
  delete pRight;
  /* 把这个键右边的键和对应的右子树左移 */
  for (i=nIndex; i < pNode->m_nCnt-1; i++)
  {
   pNode-> m_Key[ i ] = pNode-> m_Key[i+1];
   pNode-> m_Data[ i ] = pNode-> m_Data[i+1];
   pNode-> m_pChild[i+1] = pNode-> m_pChild[i+2];
  }

  pNode->m_nCnt --;
  m_nNodeCnt --;
 }
 
 /*
 * 从一个键的右子树向左子树转移一些键,使两个子树平衡
 */

 void MoveLeftNode(CGRSBTreeNode<TKey,TData,TRank>* pNode, INT nIndex)
 {
  CGRSBTreeNode<TKey,TData,TRank>* pLeft = NULL;
  CGRSBTreeNode<TKey,TData,TRank>* pRight = NULL;

  INT k = 0; /* 应转移的键的数目 */
  INT i = 0;
  INT j = 0;

  pLeft  = pNode-> m_pChild[nIndex];
  pRight = pNode-> m_pChild[nIndex + 1];
  
  k = ( pRight->m_nCnt - pLeft->m_nCnt ) / 2;

  /* 把这个键下移到它的左子树 */
  pLeft-> m_Key[pLeft->m_nCnt] = pNode-> m_Key[nIndex];
  pLeft-> m_Data[pLeft->m_nCnt] = pNode-> m_Data[nIndex];

  /* 把右子树的最左子树转移成左子树的最右子树
  * 从右子树向左子树移动 k-1 个键+子树对 */
  for (j=k-2,i=pLeft->m_nCnt+k-1; j >= 0; j--,i--)
  {
   pLeft-> m_Key[ i ]  = pRight-> m_Key[j];
   pLeft-> m_Data[ i ]  = pRight-> m_Data[j];
   pLeft-> m_pChild[ i ] = pRight-> m_pChild[j];
  }

  pLeft-> m_pChild[ pLeft->m_nCnt + k ] = pRight-> m_pChild[ k - 1 ];
  
  /* 把右子树的最左键提升到这个键的位置上 */
  pNode-> m_Key[nIndex] = pRight-> m_Key[k-1];
  pNode-> m_Data[nIndex] = pRight-> m_Data[k-1];

  /* 把右子树中的所有键值和子树左移 k 个位置 */
  pRight-> m_pChild[0] = pRight-> m_pChild[k];

  for (i=0; i<pRight->m_nCnt-k; i++)
  {
   pRight-> m_Key[ i ]  = pRight-> m_Key[ i + k ];
   pRight-> m_Data[ i ] = pRight-> m_Data[ i + k ];
   pRight-> m_pChild[ i ] = pRight-> m_pChild[ i + k ];
  }

  pRight-> m_pChild[ pRight->m_nCnt - k ] = pRight-> m_pChild[pRight->m_nCnt];
  pLeft->m_nCnt += k;
  pRight->m_nCnt -= k;
 }
 
 /*
 * 从一个键的左子树向右子树转移一些键,使两个子树平衡
 */

 void MoveRightNode( CGRSBTreeNode<TKey,TData,TRank>* pNode, INT nIndex)
 {
  CGRSBTreeNode<TKey,TData,TRank>* pLeft = NULL;
  CGRSBTreeNode<TKey,TData,TRank>* pRight = NULL;
  
  INT k = 0; /* 应转移的键的数目 */
  INT i = 0;
  INT j = 0;

  pLeft = pNode-> m_pChild[nIndex];
  pRight = pNode-> m_pChild[nIndex + 1];

  k = ( pLeft->m_nCnt - pRight->m_nCnt ) / 2;

  /* 把右子树中的所有键值和子树右移 k 个位置 */
  pRight-> m_pChild[ pRight->m_nCnt + k ] = pRight-> m_pChild[ pRight->m_nCnt ];

  for ( i = pRight->m_nCnt - 1; i >= 0; i -- )
  {
   pRight-> m_Key[i + k]  = pRight-> m_Key[ i ];
   pRight-> m_Data[i + k]  = pRight-> m_Data[ i ];
   pRight-> m_pChild[ i + k ] = pRight-> m_pChild[ i ];
  }

  /* 把这个键下移到它的右子树 */
  pRight-> m_Key[k - 1] = pNode-> m_Key[nIndex];
  pRight-> m_Data[k - 1] = pNode-> m_Data[nIndex];
  
  /* 把左子树的最右子树转移成右子树的最左子树 */

  pRight-> m_pChild[k-1] = pLeft-> m_pChild[pLeft->m_nCnt];
  
  /* 从左子树向右子树移动 k-1 个键+子树对 */
  for ( i = pLeft->m_nCnt - 1,j = k - 2; j >= 0; j --,i -- )
  {
   pRight-> m_Key[j]  = pLeft-> m_Key[ i ];
   pRight-> m_Data[j]  = pLeft-> m_Data[ i ];
   pRight-> m_pChild[j] = pLeft-> m_pChild[ i ];
  }

  /* 把左子树的最右键提升到这个键的位置上 */
  pNode-> m_Key[nIndex] = pLeft-> m_Key[ i ];
  pNode-> m_Data[nIndex] = pLeft-> m_Data[ i ];
  pLeft->m_nCnt -= k;
  pRight->m_nCnt += k;
 }

 /*
 * 把一个键和对应的右子树从一个节点中删除
 */
 void DelFromNode(CGRSBTreeNode<TKey,TData,TRank>* pNode, INT nIndex)
 {
  INT i = 0;
  /* 把所有大于要删除的键值的键左移 */
  for( i = nIndex; i < pNode->m_nCnt - 1; i ++ )
  {
   pNode-> m_Key[ i ] = pNode-> m_Key[i+1];
   pNode-> m_Data[ i ] = pNode-> m_Data[i+1];
  }

  pNode->m_nCnt --;
 }

 /*
 * 建立有两个子树和一个键的根节点
 */

 CGRSBTreeNode<TKey,TData,TRank>* NewNode(CGRSBTreeNode<TKey,TData,TRank>* pNode,const TKey& Key,const TData& Data)
 {
  CGRSBTreeNode<TKey,TData,TRank>* pTmpNode = NULL;
  pTmpNode = new CGRSBTreeNode<TKey,TData,TRank>();
  pTmpNode-> m_nCnt = 1;
  pTmpNode-> m_pChild[0] = pNode;
  pTmpNode-> m_pChild[1] = m_pNewNode;
  pTmpNode-> m_Key[0]    = Key;
  pTmpNode-> m_Data[0]   = Data;
  m_iHeight ++;
  m_nNodeCnt ++;

  return( pTmpNode );
 }

 /*
 * 释放根节点,并返回它的最左子树
 */
 CGRSBTreeNode<TKey,TData,TRank>* FreeNode(CGRSBTreeNode<TKey,TData,TRank>* pNode)
 {
  CGRSBTreeNode<TKey,TData,TRank>* pTmpNode = pNode-> m_pChild[0];
  delete pNode;
  m_iHeight --;
  m_nNodeCnt --;
  return pTmpNode;
 }

 void Error(int f,TKey Key)
 {
  if (f)
  {
   GRS_TRACE(_T("B-Tree 错误: 插入 %d 时!\n"),Key);
  }
  else
  {
   GRS_TRACE(_T("B-Tree 错误: 删除 %d 时!\n"),Key);
  }
 }

 
 
 void DelAll(CGRSBTreeNode<TKey,TData,TRank>* pNode)
 {
  INT i = 0;
  m_iAccessLevel --;

  if ( m_iAccessLevel > 0 )
  {
   for ( i = 0; i <= pNode->m_nCnt ; i ++ )
   {
    DelAll( pNode-> m_pChild[ i ] );
   }
  }

  delete pNode;

 }
public:
 BOOL Add(const TKey& Key,const TData& Data)
 {
  m_iAccessLevel = m_iHeight;

  Insert( m_pRoot, Key, Data );

  if ( m_bFlag )
  {
   m_pRoot = NewNode(m_pRoot,Key,Data);    /* 树的高度增加 */
  }

  return TRUE;
 }
 
 BOOL Del( const TKey& Key, const TData& Data )
 {
  m_iAccessLevel = m_iHeight;
  
  Remove( m_pRoot, Key, Data );

  if ( 0 == m_pRoot->m_nCnt )
  {
   m_pRoot = FreeNode( m_pRoot );
  }
  
  return TRUE;
 }

 INT GetHeight()
 {
  return m_iHeight;
 }

 INT GetKeys()
 {
  return m_nKeyCnt;
 }

 double GetPayload()
 {
  if (m_nNodeCnt==0)
  {
   return 1;
  }
  return (double) m_nKeyCnt / (double)( m_nNodeCnt *( 2 * TRank ) );
 }

 CGRSBTreeNode<TKey,TData,TRank>* Destroy ()
 {    
  m_iAccessLevel = m_iHeight;
  m_iHeight      = 0;

  return Delall(m_pRoot);

 }
public:
 
 GRSPOSITION Search(const TKey& Key, TData& Data)
 {
  INT i = 0;
  INT j = 0;
  INT k = 0;

  INT nLevel = m_iHeight;

  CGRSBTreeNode<TKey,TData,TRank>* pNode = m_pRoot; 

  while ( nLevel >= 0 )
  {
   for( i = 0, j = pNode->m_nCnt - 1;
    i < j;
    k = ( j + i ) / 2, ( Key > pNode->m_Key[ k ] ) ? ( i = k + 1) : ( j = k ) );

   if ( Key == pNode->m_Key [ i ] )
   {//找到
    Data = pNode->m_Data[i];
    return (GRSPOSITION) &pNode->m_Key[i];
   }
   
   if ( Key > pNode->m_Key [ i ] )
   {//节点在右侧
    i ++;
   }
  
   pNode = pNode->m_pChild[ i ];
   nLevel --; //到下层查找
  }

  return NULL;
 }

 CGRSBTreeNode<TKey,TData,TRank>* GetRoot()
 {
  return m_pRoot;
 }
 void Show2Tree(CTreeCtrl*pTree,HTREEITEM hItem,CGRSBTreeNode<TKey,TData,TRank>*pNode)
 {
  if( NULL == pNode )
  {
   return;
  }

  
  HTREEITEM hTmp = NULL;
  CString strTmp;
  
  for( INT i = 0; i < pNode->m_nCnt; i ++ )
  {
   if( 0 == i )
   {
    hTmp = pTree->InsertItem(_T("Child(Start)"),hItem);
    Show2Tree(pTree,hTmp,pNode->m_pChild[0]);
   }
   strTmp.Format(_T("Key(%d)"),pNode->m_Key[i]);
   
   hTmp = pTree->InsertItem(strTmp,hItem);
   Show2Tree(pTree,hTmp,pNode->m_pChild[i+1]);
  }
 }

};

 

  评论这张
 
阅读(1873)| 评论(3)

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018