B+树

孤街浪徒 提交于 2020-02-29 15:46:34

#ifndef __GOODSTREE_H__
#define __GOODSTREE_H__

#define M 200    // 树的枝数。
#define MAX_NUM  60   // 树的深度。

typedef struct _head{
 long root;
 long head;
 long tail;
 long number;
}Head;

template <class T>
class TreeNode{
public:
 int  n;
 long a[M+1];
 T    key[M];
 long prev;
 long next;
 BOOL IsLeaf;
};

//////////////////////////////////////////////////////////////////
// CGoodsTree 是M路B+树.

template <class T>
class CGoodsTree{
public:
 CGoodsTree(){ m_head.root = -1; m_IsUsed = 0;};
 ~CGoodsTree(){};

public:
 BOOL Open(CString& FileName);
 void Close();
 BOOL InsertNode(T& x);
 BOOL ChangeNode(T& x);
 BOOL DeleteNode(T& x);
 T * SearchNode(CString& pName);
 T * SearchNode(long pID);
 CList<T, T&> * SearchNodeList(long pType);//with h_id
 CList<T, T&> * SearchNodeListEx(long pPrice);// with t_id
 BOOL ChangeName(CString& pNewName, CString& pOldName);
 BOOL ChangeID(long pNewID, long pOldID);
 BOOL DeleteNode(CString& pName);
 BOOL DeleteNode(long pID);
 long GetCount();

protected:
 BOOL InsertNode(long p_root, T& x);
 BOOL ChangeNode(long p_root, T& x);
 BOOL DeleteNode(long p_parent, long p_root, T& x, int n);
 T * SearchNode(long p_root, CString& pName);
 long SearchDelete();

private:
 CFile m_hFile;
 CList<T, T&> m_List;
 T textTEMP;
 Head m_head;
 int m_IsUsed;
 long m_newLeaf;
};

template <class T>
BOOL CGoodsTree<T>::Open(CString& FileName)
{
 if(m_IsUsed++)return TRUE;
 if(!m_hFile.Open(FileName, CFile::modeReadWrite))
 {
  m_head.root = 0;
  m_head.number = 0;
  m_head.head = 0;
  if(!m_hFile.Open(FileName, CFile::modeCreate|CFile::modeReadWrite))
        {AfxMessageBox("Cann't open the file.\n");return FALSE;}
  else m_hFile.Write(&m_head,sizeof(Head));
  }
 else m_hFile.Read(&m_head,sizeof(Head));
 return TRUE;
}

template <class T>
void CGoodsTree<T>::Close()
{
 if(--m_IsUsed)return;
 m_hFile.Close();
}

template <class T>
long CGoodsTree<T>::SearchDelete()
{
 long p=sizeof(Head);
 int q;
 while(p != (long)m_hFile.GetLength())
 {
  m_hFile.Seek(p, CFile::begin);
  m_hFile.Read(&q,sizeof(int));
  if(q==0)return(p);
  p+=sizeof(TreeNode<T>);
 }
 m_hFile.Seek(0L, CFile::end);
 p=(long)m_hFile.GetPosition();
 return(p);
}

template <class T>
BOOL CGoodsTree<T>::InsertNode(T& x)
{
 TreeNode<T> tempNode;
 m_newLeaf = 0;
 InsertNode(m_head.root, x);
 if(m_newLeaf != 0) //根节点分裂了。
 {
  tempNode.n = 1;
  tempNode.a[0] = m_head.root;
  tempNode.a[1] = m_newLeaf;
  memcpy(&tempNode.key[0], &textTEMP, sizeof(T));
  m_newLeaf = SearchDelete();
  tempNode.IsLeaf = FALSE;
  m_hFile.Seek(m_newLeaf, CFile::begin);
  m_hFile.Write(&tempNode, sizeof(TreeNode<T>));
  m_head.root = m_newLeaf;
  m_hFile.Seek(0, CFile::begin);
  m_hFile.Write(&m_head, sizeof(Head));
 }
 return TRUE;
}

template <class T>
BOOL CGoodsTree<T>::InsertNode(long p_root, T& x)
{
 TreeNode<T> tempNode;
 TreeNode<T> newNode;
 long p;   // 节点插入位置。
 if(p_root == 0) // 新建立的文件。
 {
  m_hFile.Seek(p_root, CFile::end);
  m_newLeaf = (long)m_hFile.GetPosition();
  tempNode.n = 1;
  memcpy(&tempNode.key[0], &x, sizeof(T));
  tempNode.prev = tempNode.next = m_newLeaf;
  tempNode.IsLeaf = TRUE;
  m_head.head = m_head.tail = m_newLeaf;
  m_hFile.Write(&tempNode, sizeof(TreeNode<T>));
  m_head.root = m_newLeaf;
  m_head.number = 1;
  m_hFile.Seek(0, CFile::begin);
  m_hFile.Write(&m_head, sizeof(Head));
  m_newLeaf = 0;
 }
 else
 {
  m_hFile.Seek(p_root, CFile::begin);
  m_hFile.Read(&tempNode, sizeof(TreeNode<T>));
  if(tempNode.IsLeaf)  // 在叶子节点中插入。
  {
   if(tempNode.n < M)
   {
    m_newLeaf = 0;
    p = tempNode.n;
    while(tempNode.key[p - 1] > x && p > 0)
     memcpy(&tempNode.key[p], &tempNode.key[p - 1], sizeof(T)), p--;
    tempNode.a[tempNode.n] = 0;
    memcpy(&tempNode.key[p], &x, sizeof(T));
    tempNode.n++;
    m_hFile.Seek(p_root, CFile::begin);
    m_hFile.Write(&tempNode, sizeof(TreeNode<T>));
    m_head.number++;
    m_hFile.Seek(0, CFile::begin);
    m_hFile.Write(&m_head, sizeof(Head));
   }
   else
   {
    m_newLeaf = SearchDelete();
    tempNode.n = M / 2;
    newNode.n = M / 2;
    memcpy(&newNode.key[0], &tempNode.key[M / 2], sizeof(T) * M / 2);
    memcpy(&newNode.a[0], &tempNode.a[M / 2], sizeof(long) * (M / 2 + 1));
    memcpy(&textTEMP, &newNode.key[0], sizeof(T));
    newNode.next = tempNode.next;
    newNode.IsLeaf = TRUE;
    newNode.prev = p_root;
    tempNode.next = m_newLeaf;
    p = M / 2;
    if(textTEMP > x)
    {
     while(tempNode.key[p - 1] > x && p > 0)
      memcpy(&tempNode.key[p], &tempNode.key[p - 1], sizeof(T)), p--;
     memcpy(&tempNode.key[p], &x, sizeof(T));
     tempNode.n++;
    }
    else
    {
     while(newNode.key[p - 1] > x && p > 0)
      memcpy(&newNode.key[p], &newNode.key[p - 1], sizeof(T)), p--;
     memcpy(&newNode.key[p], &x, sizeof(T));
     newNode.n++;
    }
    m_hFile.Seek(p_root, CFile::begin);
    m_hFile.Write(&tempNode, sizeof(TreeNode<T>));
    m_hFile.Seek(m_newLeaf, CFile::begin);
    m_hFile.Write(&newNode, sizeof(TreeNode<T>));
    m_head.number++;
    m_hFile.Seek(0, CFile::begin);
    m_hFile.Write(&m_head, sizeof(Head));
   }
  }
  else    // 在非叶子节点中插入。
  {
   p = tempNode.n;
   while((tempNode.key[p - 1] > x) && (p > 0))p--;
   InsertNode(tempNode.a[p], x);
   if(m_newLeaf != 0) // 孩子节点分裂。
   {
    if(tempNode.n < M)
    {
     p = tempNode.n;
     while(tempNode.key[p - 1] > x && p > 0)
     {
      memcpy(&tempNode.key[p], &tempNode.key[p - 1], sizeof(T));
      tempNode.a[p + 1] = tempNode.a[p];
      p--;
     }
     memcpy(&tempNode.key[p], &textTEMP, sizeof(T));
     tempNode.a[p + 1] = m_newLeaf;
     tempNode.n++;
     m_hFile.Seek(p_root, CFile::begin);
     m_hFile.Write(&tempNode, sizeof(TreeNode<T>));
     m_newLeaf = 0;
    }
    else   // 分裂非叶子节点。
    {
     T tempKey;
     memcpy(&tempKey, &textTEMP, sizeof(T));
     tempNode.n = newNode.n = M / 2;
     newNode.IsLeaf = FALSE;
     if(tempNode.key[M / 2 - 1] > textTEMP)
     {
      memcpy(&textTEMP, &tempNode.key[M / 2 - 1], sizeof(T));
      memcpy(&newNode.key[0], &tempNode.key[tempNode.n], sizeof(T) * M / 2);
      memcpy(&newNode.a[0], &tempNode.a[tempNode.n], sizeof(long) * (M / 2 + 1));
      p = M / 2 - 1;
      while(tempNode.key[p - 1] > tempKey && p >= 0)
      {
       memcpy(&tempNode.key[p], &tempNode.key[p - 1], sizeof(T));
       tempNode.a[p + 1] = tempNode.a[p];
       p--;
      }
      memcpy(&tempNode.key[p], &tempKey, sizeof(T));
      tempNode.a[p + 1] = m_newLeaf;
     }
     else
     {
      memcpy(&newNode.key[0], &tempNode.key[tempNode.n], sizeof(T) * M / 2);
      memcpy(&newNode.a[1], &tempNode.a[tempNode.n + 1], sizeof(long) * M / 2);
      if(newNode.key[0] < textTEMP)
       memcpy(&textTEMP, &newNode.key[0], sizeof(T));
      p = 0;
      while((newNode.key[p] < tempKey) && (p < newNode.n))
      {
       memcpy(&newNode.key[p], &newNode.key[p + 1], sizeof(T));
       newNode.a[p] = newNode.a[p + 1];
       p++;
      }
      newNode.a[p] = m_newLeaf;
      if(p > 0)
       memcpy(&newNode.key[p - 1], &tempKey, sizeof(T));
     }
     m_hFile.Seek(p_root, CFile::begin);
     m_hFile.Write(&tempNode, sizeof(TreeNode<T>));
     m_newLeaf = SearchDelete();
     m_hFile.Seek(m_newLeaf, CFile::begin);
     m_hFile.Write(&newNode, sizeof(TreeNode<T>));
    }
   }
  }
 }
 return TRUE;
}

template <class T>
BOOL CGoodsTree<T>::ChangeNode(T& x)
{
 return ChangeNode(m_head.root, x);
}

template <class T>
BOOL CGoodsTree<T>::ChangeNode(long p_root, T& x)
{
 TreeNode<T> tempNode;
 m_hFile.Seek(p_root, CFile::begin);
 m_hFile.Read(&tempNode, sizeof(TreeNode<T>));
 if(tempNode.IsLeaf)
 {
  for(int i = tempNode.n; i >=0; i--)
  {
   if(tempNode.key[i] == x)
   {
    memcpy(&tempNode.key[i], &x, sizeof(T));
    m_hFile.Seek(p_root, CFile::begin);
    m_hFile.Write(&tempNode, sizeof(TreeNode<T>));
    return TRUE;
   }
  }
 }
 else
 {
  long p = tempNode.n - 1;
  while((tempNode.key[p] > x)&&(p >= 0))
   p--;
  return ChangeNode(tempNode.a[p + 1], x);
 }
 return FALSE;
}

template <class T>
BOOL CGoodsTree<T>::ChangeName(CString& pNewName, CString& pOldName)
{
 T temp, * p;
 if((p = SearchNode(pOldName)) != NULL)
 {
  memcpy(&temp, p, sizeof(T));
  DeleteNode(temp);
  sprintf(temp.name, "%s", pNewName.GetBuffer(pNewName.GetLength()));
  InsertNode(temp);
  return TRUE;
 }
 else
  return FALSE;
}

template <class T>
BOOL CGoodsTree<T>::ChangeID(long pNewID, long pOldID)
{
 T temp, * p;
 if((p = SearchNode(pOldID)) != NULL)
 {
  memcpy(&temp, p, sizeof(T));
  DeleteNode(temp);
  temp.id = pNewID;
  InsertNode(temp);
  return TRUE;
 }
 else
  return FALSE;
}

template <class T>
T * CGoodsTree<T>::SearchNode(CString& pName)
{
 if(m_head.root == 0)return NULL;
 return SearchNode(m_head.root, pName);
}

template <class T>
T * CGoodsTree<T>::SearchNode(long p_root, CString& pName)
{
 TreeNode<T> tempNode;
 m_hFile.Seek(p_root, CFile::begin);
 m_hFile.Read(&tempNode, sizeof(TreeNode<T>));
 if(tempNode.IsLeaf)
 {
  for(int i = tempNode.n; i >=0; i--)
  {
   if(strcmp(tempNode.key[i].name, pName.GetBuffer(pName.GetLength())) == 0)
   {
    memcpy(&textTEMP, &tempNode.key[i], sizeof(T));
    return &textTEMP;
   }
  }
 }
 else
 {
  long p = tempNode.n - 1;
  while((strcmp(tempNode.key[p].name, pName.GetBuffer(pName.GetLength())) > 0)&&(p >= 0))
   p--;
  return SearchNode(tempNode.a[p + 1], pName);
 }
 return NULL;
}

template <class T>
T * CGoodsTree<T>::SearchNode(long pID)
{
 if(m_head.head == 0)return NULL;
 TreeNode<T> tempNode;
 long p = m_head.head;
 do{
  m_hFile.Seek(p, CFile::begin);
  m_hFile.Read(&tempNode, sizeof(TreeNode<T>));
  for(long i = 0; i < tempNode.n; i++)
   if(tempNode.key[i].id == pID)
   {
    memcpy(&textTEMP, &tempNode.key[i], sizeof(T));
    return &textTEMP;
   }
  p = tempNode.next;
 }while(p != m_head.head);
 return NULL;
}

template <class T>
CList<T, T&> * CGoodsTree<T>::SearchNodeList(long pType)
// Search from B+Tree with h_id.
{
 m_List.RemoveAll();
 if(m_head.head == 0)return &m_List;
 TreeNode<T> tempNode;
 long p = m_head.head;
 do{
  m_hFile.Seek(p, CFile::begin);
  m_hFile.Read(&tempNode, sizeof(TreeNode<T>));
  for(long i = 0; i < tempNode.n; i++)
   if(tempNode.key[i].h_id == pType)
    m_List.AddTail(tempNode.key[i]);
  p = tempNode.next;
 }while(p != m_head.head);
 return &m_List;
}

template <class T>
CList<T, T&> * CGoodsTree<T>::SearchNodeListEx(long pPrice)
// Search from B+Tree with t_id.
{
 m_List.RemoveAll();
 if(m_head.head == 0)return &m_List;
 TreeNode<T> tempNode;
 long p = m_head.head;
 do{
  m_hFile.Seek(p, CFile::begin);
  m_hFile.Read(&tempNode, sizeof(TreeNode<T>));
  for(long i = 0; i < tempNode.n; i++)
   if(tempNode.key[i].t_id == pPrice)
    m_List.AddTail(tempNode.key[i]);
  p = tempNode.next;
 }while(p != m_head.head);
 return &m_List;
}

template <class T>
BOOL CGoodsTree<T>::DeleteNode(T& x)
{
 m_newLeaf = 0;
 if(m_head.root == 0)return FALSE;
 DeleteNode(m_head.root, m_head.root, x, 0);
 if(m_newLeaf != 0) //根节点被删除了。
 {
  m_head.root = m_newLeaf;
  m_hFile.Seek(0, CFile::begin);
  m_hFile.Write(&m_head, sizeof(Head));
 }
 return TRUE;
}

template <class T>
BOOL CGoodsTree<T>::DeleteNode(long p_parent, long p_root, T& x, int n)
{
 TreeNode<T> tempNode, tempNode1, tempNode2;
 m_hFile.Seek(p_root, CFile::begin);
 m_hFile.Read(&tempNode, sizeof(TreeNode<T>));
 long p = 0, q = 0; // q is tempNode2's point.
 if(tempNode.IsLeaf)
 {
  if((tempNode.n > M / 2) || (p_parent == p_root))
  {
   while((tempNode.key[p] < x)&&(p < tempNode.n))p++;
   if(tempNode.key[p] == x)
    for(;p < tempNode.n; p++)
     memcpy(&tempNode.key[p], &tempNode.key[p + 1], sizeof(T));
   else
    return FALSE;
   tempNode.n--;
  }
  else
  { // 调整兄弟节点。
   m_hFile.Seek(p_parent, CFile::begin);
   m_hFile.Read(&tempNode1, sizeof(TreeNode<T>));
   if(tempNode1.n > n)
   { // 与右兄弟调整。
    q = tempNode1.a[n + 1];
    m_hFile.Seek(q, CFile::begin);
    m_hFile.Read(&tempNode2, sizeof(TreeNode<T>));
    if(tempNode2.n > M / 2)
    {
     memcpy(&tempNode.key[tempNode.n], &tempNode2.key[0], sizeof(T));
     memcpy(&tempNode1.key[n], &tempNode2.key[1], sizeof(T));
     for(p = 0; p < tempNode2.n; p++)
      memcpy(&tempNode2.key[p], &tempNode2.key[p + 1], sizeof(T));
     tempNode2.n--;
     p = 0;
     while((tempNode.key[p] < x)&&(p < tempNode.n))p++;
     if(tempNode.key[p] == x)
      for(;p < tempNode.n + 1; p++)
       memcpy(&tempNode.key[p], &tempNode.key[p + 1], sizeof(T));
     else
      return FALSE;
    }
    else
    { // 合并叶子节点。
     for(p = n; p < tempNode1.n; p++)
     {
      memcpy(&tempNode1.key[p], &tempNode1.key[p + 1], sizeof(T));
      tempNode1.a[p + 1] = tempNode1.a[p + 2];
     }
     tempNode1.n--;
     for(p = 0; p < tempNode2.n; p++)
      memcpy(&tempNode.key[tempNode.n + p], &tempNode2.key[p], sizeof(T));
     tempNode.n += tempNode2.n - 1;
     tempNode2.n = 0;
     tempNode.next = tempNode2.next;
     p = 0;
     while((tempNode.key[p] < x)&&(p < tempNode.n))p++;
     if(tempNode.key[p] == x)
      for(;p < tempNode.n + 1; p++)
       memcpy(&tempNode.key[p], &tempNode.key[p + 1], sizeof(T));
     else
      return FALSE;
     m_newLeaf = p_root;
    }
   }
   else
   { // 与左兄弟调整。
    q = tempNode1.a[n - 1];
    m_hFile.Seek(q, CFile::begin);
    m_hFile.Read(&tempNode2, sizeof(TreeNode<T>));
    if(tempNode2.n > M / 2)
    {
     memcpy(&tempNode1.key[n], &tempNode2.key[tempNode2.n - 1], sizeof(T));
     tempNode2.n--;
     p = tempNode.n - 1;
     while((tempNode.key[p] > x)&&(p > 0))p--;
     if(tempNode.key[p] == x)
      for(;p >= 0; p--)
       memcpy(&tempNode.key[p], &tempNode.key[p - 1], sizeof(T));
     else
      return FALSE;
     memcpy(&tempNode.key[0], &tempNode2.key[tempNode2.n], sizeof(T));
    }
    else
    { // 合并叶子节点。
     for(p = n; p < tempNode1.n; p++)
     {
      memcpy(&tempNode1.key[p], &tempNode1.key[p + 1], sizeof(T));
      tempNode1.a[p + 1] = tempNode1.a[p + 2];
     }
     tempNode1.n--;
     for(p = 0; p < tempNode.n; p++)
      memcpy(&tempNode2.key[tempNode2.n + p], &tempNode.key[p], sizeof(T));
     tempNode2.n += tempNode.n - 1;
     tempNode.n = 0;
     tempNode2.next = tempNode.next;
     p = 0;
     while((tempNode2.key[p] < x)&&(p < tempNode2.n))p++;
     if(tempNode2.key[p] == x)
      for(;p < tempNode2.n; p++)
       memcpy(&tempNode2.key[p], &tempNode2.key[p + 1], sizeof(T));
     else
      return FALSE;
     m_newLeaf = q;
    }
   }
   m_hFile.Seek(p_parent, CFile::begin);
   m_hFile.Write(&tempNode1, sizeof(TreeNode<T>));
   m_hFile.Seek(q, CFile::begin);
   m_hFile.Write(&tempNode2, sizeof(TreeNode<T>));
  }
  m_hFile.Seek(p_root, CFile::begin);
  m_hFile.Write(&tempNode, sizeof(TreeNode<T>));
 }
 else
 {
  p = tempNode.n - 1;
  while((tempNode.key[p] > x)&&(p >= 0))p--;
  DeleteNode(p_root, tempNode.a[p + 1], x, p + 1);
  if(m_newLeaf != 0)
  {
   m_hFile.Seek(p_root, CFile::begin);
   m_hFile.Read(&tempNode, sizeof(TreeNode<T>));
   if(tempNode.n == 0)return TRUE;
   if((tempNode.n >= M / 2)||(p_parent == p_root))
    m_newLeaf = 0;
   else
   {
    m_hFile.Seek(p_parent, CFile::begin);
    m_hFile.Read(&tempNode1, sizeof(TreeNode<T>));
    if(tempNode1.n > n)
    { // 与右兄弟调整。
     q = tempNode1.a[n + 1];
     m_hFile.Seek(q, CFile::begin);
     m_hFile.Read(&tempNode2, sizeof(TreeNode<T>));
     if(tempNode2.n > M / 2)
     {
      memcpy(&tempNode.key[tempNode.n], &tempNode1.key[n - 1], sizeof(T));
      tempNode.a[tempNode.n + 1] = tempNode2.a[0];
      tempNode.n++;
      memcpy(&tempNode1.key[n - 1], &tempNode2.key[0], sizeof(T));
      for(p = 0; p <= tempNode2.n; p++)
      {
       memcpy(&tempNode2.key[p], &tempNode2.key[p + 1], sizeof(T));
       tempNode2.a[p] = tempNode2.a[p + 1];
      }
      tempNode2.n--;
      m_newLeaf = 0;
     }
     else
     { // 合并叶子节点。
      memcpy(&tempNode.key[tempNode.n], &tempNode1.key[n - 1], sizeof(T));
      tempNode.n++;
      for(p = n - 1; p < tempNode1.n; p++)
      {
       memcpy(&tempNode1.key[p], &tempNode1.key[p + 1], sizeof(T));
       tempNode1.a[p + 1] = tempNode1.a[p + 2];
      }
      tempNode1.n--;
      for(p = 0; p < tempNode2.n; p++)
      {
       memcpy(&tempNode.key[tempNode.n + p], &tempNode2.key[p], sizeof(T));
       tempNode.a[tempNode.n + p] = tempNode2.a[p];
      }
      tempNode.a[tempNode.n + p] = tempNode2.a[p];
      tempNode.n += tempNode2.n;
      tempNode2.n = 0;
      m_newLeaf = p_root;
     }
    }
    else
    { // 与左兄弟调整。
     q = tempNode1.a[n - 1];
     m_hFile.Seek(q, CFile::begin);
     m_hFile.Read(&tempNode2, sizeof(TreeNode<T>));
     if(tempNode2.n > M / 2)
     {
      p = tempNode.n;
      while(--p >= 0)
      {
       memcpy(&tempNode.key[p + 1], &tempNode.key[p], sizeof(T));
       tempNode.a[p + 2] = tempNode.a[p + 1];
      }
      tempNode.a[1] = tempNode.a[0];
      tempNode.a[0] = tempNode2.a[tempNode2.n];
      memcpy(&tempNode.key[0], &tempNode1.key[n - 1], sizeof(T));
      tempNode.n++;
      tempNode2.n--;
      memcpy(&tempNode1.key[n - 1], &tempNode2.key[tempNode2.n], sizeof(T));
      m_newLeaf = 0;
     }
     else
     { // 合并叶子节点。
      memcpy(&tempNode2.key[tempNode2.n], &tempNode1.key[n - 1], sizeof(T));
      tempNode2.n++;
      for(p = n; p < tempNode1.n; p++)
      {
       memcpy(&tempNode1.key[p], &tempNode1.key[p + 1], sizeof(T));
       tempNode1.a[p + 1] = tempNode1.a[p + 2];
      }
      tempNode1.n--;
      for(p = 0; p < tempNode.n; p++)
      {
       memcpy(&tempNode2.key[tempNode2.n + p], &tempNode.key[p], sizeof(T));
       tempNode2.a[tempNode2.n + p] = tempNode.a[p];
      }
      tempNode2.a[tempNode2.n + p] = tempNode.a[p];
      tempNode2.n += tempNode.n;
      tempNode.n = 0;
      m_newLeaf = q;
     }
    }
    m_hFile.Seek(q, CFile::begin);
    m_hFile.Write(&tempNode2, sizeof(TreeNode<T>));
    m_hFile.Seek(p_parent, CFile::begin);
    m_hFile.Write(&tempNode1, sizeof(TreeNode<T>));
    m_hFile.Seek(p_root, CFile::begin);
    m_hFile.Write(&tempNode, sizeof(TreeNode<T>));
   }
  }
 }
 return TRUE;
}

template <class T>
BOOL CGoodsTree<T>::DeleteNode(CString& pName)
{
 T temp, * p;
 if((p = SearchNode(pName)) != NULL)
 {
  memcpy(&temp, p, sizeof(T));
  DeleteNode(temp);
  return TRUE;
 }
 else
  return FALSE;
}

template <class T>
BOOL CGoodsTree<T>::DeleteNode(long pID)
{
 T temp, * p;
 if((p = SearchNode(pID)) != NULL)
 {
  memcpy(&temp, p, sizeof(T));
  DeleteNode(temp);
  return TRUE;
 }
 else
  return FALSE;
}

template <class T>
long CGoodsTree<T>::GetCount()
{
 return m_head.number;
}

#endif

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!