欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

數(shù)據(jù)結(jié)構(gòu)(十三)——樹

數(shù)據(jù)結(jié)構(gòu)(十三)——樹

一、樹的簡介

1、樹的簡介

樹是一種非線性的數(shù)據(jù)結(jié)構(gòu),是由n(n >=0)個結(jié)點(diǎn)組成的有限集合。
如果n==0,樹為空樹。
如果n>0,
樹有一個特定的結(jié)點(diǎn),根結(jié)點(diǎn)
根結(jié)點(diǎn)只有直接后繼,沒有直接前驅(qū)。
除根結(jié)點(diǎn)以外的其他結(jié)點(diǎn)劃分為m(m>=0)個互不相交的有限集合,T0,T1,T2,...,Tm-1,每個結(jié)合是一棵樹,稱為根結(jié)點(diǎn)的子樹。
樹的示例如下:
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供達(dá)茂旗網(wǎng)站建設(shè)、達(dá)茂旗做網(wǎng)站、達(dá)茂旗網(wǎng)站設(shè)計、達(dá)茂旗網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、達(dá)茂旗企業(yè)網(wǎng)站模板建站服務(wù),10多年達(dá)茂旗做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。

2、樹的度

樹的結(jié)點(diǎn)包含一個數(shù)據(jù)和多個指向子樹的分支
結(jié)點(diǎn)擁有的子樹的數(shù)量為結(jié)點(diǎn)的度,度為0的結(jié)點(diǎn)是葉結(jié)點(diǎn),度不為0的結(jié)點(diǎn)為分支結(jié)點(diǎn),樹的度定義為樹的所有結(jié)點(diǎn)中度的最大值。
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

3、樹的前驅(qū)和后繼

結(jié)點(diǎn)的直接后繼稱為結(jié)點(diǎn)的孩子,結(jié)點(diǎn)稱為孩子的雙親。
結(jié)點(diǎn)的孩子的孩子稱為結(jié)點(diǎn)的孫子,結(jié)點(diǎn)稱為子孫的祖先。
同一個雙親的孩子之間互稱兄弟。
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

4、樹中結(jié)點(diǎn)的層次

數(shù)據(jù)結(jié)構(gòu)(十三)——樹
樹中根結(jié)點(diǎn)為第1層,根結(jié)點(diǎn)的孩子為第2層,依次類推。
樹中結(jié)點(diǎn)的最大層次稱為樹的深度或高度

5、樹的有序性

如果樹中結(jié)點(diǎn)的各子樹從左向右是有序的,子樹間不能互換位置,則稱該樹為有序樹,否則為無序樹。
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

6、森林

森林是由n棵互不相交的樹組成的集合。
三棵樹組成的森林如下:
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

二、樹的抽象實(shí)現(xiàn)

1、樹的抽象實(shí)現(xiàn)

樹在程序中表現(xiàn)為一種特殊的數(shù)據(jù)類型。
樹的抽象實(shí)現(xiàn)如下:

template <typename T>
  class Tree:public Object
  {
  protected:
    TreeNode<T>* m_root;//根結(jié)點(diǎn)
  public:
    Tree(){m_root = NULL;}
    //插入結(jié)點(diǎn)
    virtual bool insert(TreeNode<T>* node) = 0;
    virtual bool insert(const T& value, TreeNode<T>* parent) = 0;
    //刪除結(jié)點(diǎn)
    virtual SharedPointer< Tree<T> > remove(const T& value) = 0;
    virtual SharedPointer< Tree<T> > remove(TreeNode<T>* node) = 0;
    //查找結(jié)點(diǎn)
    virtual TreeNode<T>* find(const T& value)const = 0;
    virtual TreeNode<T>* find(TreeNode<T>* node)const = 0;
    //根結(jié)點(diǎn)訪問函數(shù)
    virtual TreeNode<T>* root()const = 0;
    //樹的度訪問函數(shù)
    virtual int degree()const = 0;
    //樹的高度訪問函數(shù)
    virtual int height()const = 0;
    //樹的結(jié)點(diǎn)數(shù)目訪問函數(shù)
    virtual int count()const = 0;
    //清空樹
    virtual void clear() = 0;
  };

2、樹結(jié)點(diǎn)的抽象實(shí)現(xiàn)

樹中的結(jié)點(diǎn)表現(xiàn)為一種特殊的數(shù)據(jù)類型。
結(jié)點(diǎn)的抽象實(shí)現(xiàn)如下:

template <typename T>
  class TreeNode:public Object
  {
  public:
    T value;
    TreeNode<T>* parent;
    TreeNode()
    {
      parent = NULL;
    }
    virtual ~TreeNode() = 0;
  };
  template <typename T>
  TreeNode<T>::~TreeNode()
  {
  }

三、樹的操作

1、樹和樹結(jié)點(diǎn)的存儲結(jié)構(gòu)實(shí)現(xiàn)

GTreeNode能夠包含任意多個指向后繼結(jié)點(diǎn)的指針。

template <typename T>
  class GTreeNode:public TreeNode<T>
  {
  protected:
    LinkedList<GTreeNode<T>*> m_children;
  };
GTree為通用樹結(jié)構(gòu),每個結(jié)點(diǎn)可以存在多個后繼結(jié)點(diǎn)。
  template <typename T>
  class GTree:public Tree<T>
  {
  public:
  };

數(shù)據(jù)結(jié)構(gòu)(十三)——樹
每個樹結(jié)點(diǎn)包含指向前驅(qū)結(jié)點(diǎn)的指針,優(yōu)點(diǎn)在于可以將非線性的樹轉(zhuǎn)化為線性的結(jié)構(gòu)。
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

2、樹中結(jié)點(diǎn)的查找

A、基于數(shù)據(jù)元素值的查找
定義在任意一個結(jié)點(diǎn)為根結(jié)點(diǎn)的樹中查找指定數(shù)據(jù)元素值所在的結(jié)點(diǎn)的函數(shù)。
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

GTreeNode<T>* find(GTreeNode<T>* node, const T& value)const
    {
      GTreeNode<T>* ret = NULL;
      if(node != NULL)
      {
          //如果根結(jié)點(diǎn)的就是目標(biāo)結(jié)點(diǎn)
          if(node->value == value)
          {
              ret =  node;
          }
          else
          {
              //遍歷根節(jié)點(diǎn)的子結(jié)點(diǎn)
              for(node->m_children.move(0); !node->m_children.end() && (ret == NULL); node->m_children.next())
              {
                  //對每個子子結(jié)點(diǎn)進(jìn)行查找
                  ret = find(node->m_children.current(), value);
              }
          }
      }
      return ret;
    }

    //查找結(jié)點(diǎn)
    virtual GTreeNode<T>* find(const T& value)const
    {
      return find(root(), value);
    }

B、基于樹中結(jié)點(diǎn)的查找
定義在任意一個結(jié)點(diǎn)為根結(jié)點(diǎn)的樹中查找指定結(jié)點(diǎn)的函數(shù)
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

 GTreeNode<T>* find(GTreeNode<T>* node, GTreeNode<T>* obj)const
    {
      GTreeNode<T>* ret = NULL;
      //根結(jié)點(diǎn)為目標(biāo)結(jié)點(diǎn)
      if(node == obj)
      {
          ret =  node;
      }
      else
      {
          if(node != NULL)
          {
              //遍歷子結(jié)點(diǎn)
              for(node->m_children.move(0); !node->m_children.end() && (ret == NULL); node->m_children.next())
              {
                  ret = find(node->m_children.current(), obj);
              }
          }
      }
      return ret;
    }

    virtual GTreeNode<T>* find(TreeNode<T>* node)const
    {
      return find(root(), dynamic_cast<GTreeNode<T>*>(node));
    }

3、樹中結(jié)點(diǎn)的插入

樹是非線性的數(shù)據(jù)結(jié)構(gòu),無法采用下標(biāo)的方式定位數(shù)據(jù)元素,由于每個結(jié)點(diǎn)的都有一個唯一的前驅(qū)結(jié)點(diǎn)(父結(jié)點(diǎn)),因此必須找到前驅(qū)結(jié)點(diǎn)才能找到插入的位置。
A、插入結(jié)點(diǎn)
插入結(jié)點(diǎn)的流程
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

bool insert(TreeNode<T>* node)
    {
      bool ret = true;
      if(node != NULL)
      {
          //樹為空,插入結(jié)點(diǎn)為根結(jié)點(diǎn)
          if(this->m_root == NULL)
          {
              node->parent = NULL;
              this->m_root = node;
          }
          else
          {
              //找到插入結(jié)點(diǎn)的父結(jié)點(diǎn)
              GTreeNode<T>* np = find(node->parent);
              if(np != NULL)
              {
                  GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);
                  //如果子結(jié)點(diǎn)中無該結(jié)點(diǎn),插入結(jié)點(diǎn)
                  if(np->m_children.find(n) < 0)
                  {
                      ret = np->m_children.insert(n);
                  }
              }
              else
              {
                  THROW_EXCEPTION(InvalidOperationException, "Invalid node...");
              }
          }
      }
      else
      {
          THROW_EXCEPTION(InvalidParameterException, "Parameter is invalid...");
      }
      return ret;
    }

B、插入數(shù)據(jù)元素
插入數(shù)據(jù)元素到樹中的流程如下:
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

bool insert(const T& value, TreeNode<T>* parent)
    {
      bool ret = true;
      GTreeNode<T>* node = GTreeNode<T>::NewNode();
      if(node != NULL)
      {
          node->value = value;
          node->parent = parent;
          insert(node);
      }
      else
      {
          THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory...");
      }
      return ret;
    }

4、樹中結(jié)點(diǎn)的清除

樹的清空操作需要將樹中所有的結(jié)點(diǎn)清除,并釋放分配在堆中的結(jié)點(diǎn)。
定義清除樹中每個結(jié)點(diǎn)的函數(shù)
數(shù)據(jù)結(jié)構(gòu)(十三)——樹
如果樹中的結(jié)點(diǎn)可能分配在棧上和堆上,需要將堆空間的結(jié)點(diǎn)進(jìn)行釋放。
根據(jù)內(nèi)存地址不能準(zhǔn)確判斷結(jié)點(diǎn)所在的存儲空間,清除時存儲在棧上的結(jié)點(diǎn)并不需要釋放,只需要釋放存儲在堆空間的結(jié)點(diǎn)。
使用工廠模式對分配在堆空間的結(jié)點(diǎn)進(jìn)行定制。
A、GTreeNode類中增加保護(hù)的堆空間標(biāo)識成員m_flag
B、重載GTreeNode的operrator new操作符,聲明為保護(hù)
C、提供工廠方法NewNode(),在工廠方法中創(chuàng)建堆空間的結(jié)點(diǎn),并將m_flag標(biāo)識置為true。

template <typename T>
  class GTreeNode:public TreeNode<T>
  {
  protected:
    bool m_flag;//堆空間標(biāo)識
    //重載new操作符,聲明為保護(hù)
    void* operator new(unsigned int size)throw()
    {
      return Object::operator new(size);
    }

  public:
    LinkedList<GTreeNode<T>*> m_children;
    GTreeNode()
    {
      //棧上分配的空間標(biāo)識為false
      m_flag = false;
    }
    //工廠方法,創(chuàng)建堆空間的結(jié)點(diǎn)
    static GTreeNode<T>* NewNode()
    {
      GTreeNode<T>* ret = new GTreeNode<T>();
      if(ret != NULL)
      {
          //堆空間的結(jié)點(diǎn)標(biāo)識為true
          ret->m_flag = true;
      }
      return ret;
    }
    //堆空間結(jié)點(diǎn)標(biāo)識訪問函數(shù)
    bool flag()const
    {
      return m_flag;
    }
  };
結(jié)點(diǎn)的釋放:
    void free(GTreeNode<T>* node)
    {
      if(node != NULL)
      {
          for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
          {
              free(node->m_children.current());
          }
          //如果結(jié)點(diǎn)存儲在堆空間
          if(node->flag())
             delete node;//釋放
      }
    }
清空樹:
    void clear()
    {
        free(root());
        this->m_root = NULL;
    }

5、樹中結(jié)點(diǎn)的刪除

刪除函數(shù)的設(shè)計要點(diǎn):
將被刪除結(jié)點(diǎn)的子樹進(jìn)行刪除;
刪除函數(shù)返回一顆堆空間的樹;
具體返回值為指向樹的智能指針;
具體的結(jié)點(diǎn)刪除功能函數(shù)如下:
將node為根結(jié)點(diǎn)的子樹從原來的樹中刪除,ret作為子樹返回
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

void remove(GTreeNode<T>* node, GTree<T>*& ret)
    {
      ret = new GTree<T>();
      if(ret != NULL)
      {
          //如果刪除的結(jié)點(diǎn)是根結(jié)點(diǎn)
          if(root() == node)
          {
              this->m_root = NULL;
          }
          else
          {
              //獲取刪除結(jié)點(diǎn)的父結(jié)點(diǎn)的子結(jié)點(diǎn)鏈表
              LinkedList<GTreeNode<T>*>& child = dynamic_cast<GTreeNode<T>*>(node->parent)->m_children;
              //從鏈表中刪除結(jié)點(diǎn)
              child.remove(child.find(node));
              //結(jié)點(diǎn)的父結(jié)點(diǎn)置NULL
              node->parent = NULL;
          }
          //將刪除結(jié)點(diǎn)賦值給創(chuàng)建的樹ret的根結(jié)點(diǎn)
          ret->m_root = node;
      }
      else
      {
          THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory...");
      }
    }

A、基于刪除數(shù)據(jù)元素值刪除結(jié)點(diǎn)

 SharedPointer<Tree<T>> remove(const T& value)
    {
      GTree<T>* ret = NULL;
      //找到結(jié)點(diǎn)
      GTreeNode<T>* node = find(value);
      if(node != NULL)
      {
          remove(node, ret);
      }
      else
      {
          THROW_EXCEPTION(InvalidParameterException, "Parameter invalid...");
      }
      return ret;
    }

B、基于結(jié)點(diǎn)刪除

 SharedPointer<Tree<T>> remove(TreeNode<T>* node)
    {
      GTree<T>* ret = NULL;
      node = find(node);
      if(node != NULL)
      {
          remove(dynamic_cast<GTreeNode<T>*>(node), ret);
      }
      else
      {
          THROW_EXCEPTION(InvalidParameterException, "Parameter invalid...");
      }
      return ret;
    }

6、樹中結(jié)點(diǎn)的屬性操作

A、樹中結(jié)點(diǎn)的數(shù)量
以node為結(jié)點(diǎn)的子樹的結(jié)點(diǎn)數(shù)量,遞歸模型如下:
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

int count(GTreeNode<T>* node) const
    {
      int ret = 0;
      if(node != NULL)
      {
          ret = 1;//根結(jié)點(diǎn)
          //遍歷根節(jié)點(diǎn)的子結(jié)點(diǎn)
          for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
          {
              ret += count(node->m_children.current());
          }
      }
      return ret;
    }
    //樹的結(jié)點(diǎn)數(shù)目訪問函數(shù)
    int count()const
    {
        count(root());
    }

B、樹的度
結(jié)點(diǎn)node為根的樹的度的功能函數(shù)的遞歸模型如下:
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

int degree(GTreeNode<T>* node) const
    {
      int ret = 0;
      if(node != NULL)
      {
          //結(jié)點(diǎn)的子結(jié)點(diǎn)的數(shù)量
          ret = node->m_children.length();
          //遍歷子結(jié)點(diǎn)
          for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
          {
              int d = degree(node->m_children.current());
              if(ret < d)
              {
                  ret = d;
              }
          }
      }
      return ret;
    }

    //樹的度訪問函數(shù)
    int degree()const
    {
        return degree(root());
    }

C、樹的高度
結(jié)點(diǎn)node為根的樹的高度的功能函數(shù)的遞歸模型如下:
數(shù)據(jù)結(jié)構(gòu)(十三)——樹

int height(GTreeNode<T>* node)const
    {
      int ret = 0;
      if(node != NULL)
      {
          //遍歷子結(jié)點(diǎn)
          for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
          {
              //當(dāng)前結(jié)點(diǎn)的高度
              int h = height(node->m_children.current());
              if(ret < h)
              {
                  ret = h;
              }
          }
          ret = ret + 1;
      }
      return ret;
    }
    //樹的高度訪問函數(shù)
    int height()const
    {
        height(root());
    }

7、樹中結(jié)點(diǎn)的遍歷

樹是一種非線性的數(shù)據(jù)結(jié)構(gòu),遍歷樹中結(jié)點(diǎn)可以采用游標(biāo)的方式。
A、在樹中定義一個游標(biāo)(GTreeNode<T>* node)
B、遍歷開始前將游標(biāo)指向根結(jié)點(diǎn)
C、獲取游標(biāo)指向的數(shù)據(jù)元素
D、通過結(jié)點(diǎn)中的m_children成員移動游標(biāo)
數(shù)據(jù)結(jié)構(gòu)(十三)——樹
將根結(jié)點(diǎn)壓入隊列中

 bool begin()
    {
      bool ret = (root() != NULL);
      if(ret)
      {
          //清空隊列
          m_queue.clear();
          //根節(jié)點(diǎn)加入隊列
          m_queue.add(root());
      }
      return ret;
    }

判斷隊列是否為空

 bool end()
    {
        return (m_queue.length() == 0);
    }

隊頭元素彈出,將隊頭元素的孩子壓入隊列中

 bool next()
    {
      bool ret = (m_queue.length() > 0);
      if(ret)
      {
          GTreeNode<T>* node = m_queue.front();
          m_queue.remove();//隊頭元素出隊
          //將隊頭元素的子結(jié)點(diǎn)入隊
          for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
          {
              m_queue.add(node->m_children.current());
          }
      }
      return ret;
    }

訪問隊頭元素指向的數(shù)據(jù)元素

T current()
    {
      if(!end())
      {
          return m_queue.front()->value;
      }
      else
      {
          THROW_EXCEPTION(InvalidOperationException, "No value at current Node...");
        }
    }

四、通用樹結(jié)構(gòu)的實(shí)現(xiàn)

1、通用樹節(jié)點(diǎn)的實(shí)現(xiàn)

 template <typename T>
  class GTreeNode:public TreeNode<T>
  {
  protected:
    bool m_flag;//堆空間標(biāo)識
    //重載new操作符,聲明為保護(hù)
    void* operator new(unsigned int size)throw()
    {
      return Object::operator new(size);
    }
    GTreeNode(const GTreeNode<T>& other);
    GTreeNode<T>& operator = (const GTreeNode<T>& other);

  public:
    LinkedList<GTreeNode<T>*> m_children;
    GTreeNode()
    {
      //棧上分配的空間標(biāo)識為false
      m_flag = false;
    }
    //工廠方法,創(chuàng)建堆空間的結(jié)點(diǎn)
    static GTreeNode<T>* NewNode()
    {
      GTreeNode<T>* ret = new GTreeNode<T>();
      if(ret != NULL)
      {
          //堆空間的結(jié)點(diǎn)標(biāo)識為true
          ret->m_flag = true;
      }
      return ret;
    }
    //堆空間結(jié)點(diǎn)標(biāo)識訪問函數(shù)
    bool flag()const
    {
      return m_flag;
    }
  };

2、通用樹的實(shí)現(xiàn)

 template <typename T>
  class GTree:public Tree<T>
  {
  protected:
    LinkedQueue<GTreeNode<T>*> m_queue;
    GTree(const GTree<T>& other);
    GTree<T>& operator=(const GTree<T>& other);
    GTreeNode<T>* find(GTreeNode<T>* node, const T& value)const
    {
      GTreeNode<T>* ret = NULL;
      if(node != NULL)
      {
          //如果根結(jié)點(diǎn)的就是目標(biāo)結(jié)點(diǎn)
          if(node->value == value)
          {
              ret =  node;
          }
          else
          {
              //遍歷根節(jié)點(diǎn)的子結(jié)點(diǎn)
              for(node->m_children.move(0); !node->m_children.end() && (ret == NULL); node->m_children.next())
              {
                  //對每個子子結(jié)點(diǎn)進(jìn)行查找
                  ret = find(node->m_children.current(), value);
              }
          }
      }
      return ret;
    }
    GTreeNode<T>* find(GTreeNode<T>* node, GTreeNode<T>* obj)const
    {
      GTreeNode<T>* ret = NULL;
      //根結(jié)點(diǎn)為目標(biāo)結(jié)點(diǎn)
      if(node == obj)
      {
          ret =  node;
      }
      else
      {
          if(node != NULL)
          {
              //遍歷子結(jié)點(diǎn)
              for(node->m_children.move(0); !node->m_children.end() && (ret == NULL); node->m_children.next())
              {
                  ret = find(node->m_children.current(), obj);
              }
          }
      }
      return ret;
    }

    void free(GTreeNode<T>* node)
    {
      if(node != NULL)
      {
          for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
          {
              free(node->m_children.current());
          }
          //如果結(jié)點(diǎn)存儲在堆空間
          if(node->flag())
             delete node;//釋放
      }
    }

    void remove(GTreeNode<T>* node, GTree<T>*& ret)
    {
      ret = new GTree<T>();
      if(ret != NULL)
      {
          //如果刪除的結(jié)點(diǎn)是根結(jié)點(diǎn)
          if(root() == node)
          {
              this->m_root = NULL;
          }
          else
          {
              //獲取刪除結(jié)點(diǎn)的父結(jié)點(diǎn)的子結(jié)點(diǎn)鏈表
              LinkedList<GTreeNode<T>*>& child = dynamic_cast<GTreeNode<T>*>(node->parent)->m_children;
              //從鏈表中刪除結(jié)點(diǎn)
              child.remove(child.find(node));
              //結(jié)點(diǎn)的父結(jié)點(diǎn)置NULL
              node->parent = NULL;
          }
          //將刪除結(jié)點(diǎn)賦值給創(chuàng)建的樹ret的根結(jié)點(diǎn)
          ret->m_root = node;
      }
      else
      {
          THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory...");
      }
    }

    int count(GTreeNode<T>* node) const
    {
      int ret = 0;
      if(node != NULL)
      {
          ret = 1;//根結(jié)點(diǎn)
          //遍歷根節(jié)點(diǎn)的子結(jié)點(diǎn)
          for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
          {
              ret += count(node->m_children.current());
          }
      }
      return ret;
    }

    int height(GTreeNode<T>* node)const
    {
      int ret = 0;
      if(node != NULL)
      {
          //遍歷子結(jié)點(diǎn)
          for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
          {
              //當(dāng)前結(jié)點(diǎn)的高度
              int h = height(node->m_children.current());
              if(ret < h)
              {
                  ret = h;
              }
          }
          ret = ret + 1;
      }
      return ret;
    }

    int degree(GTreeNode<T>* node) const
    {
      int ret = 0;
      if(node != NULL)
      {
          //結(jié)點(diǎn)的子結(jié)點(diǎn)的數(shù)量
          ret = node->m_children.length();
          //遍歷子結(jié)點(diǎn)
          for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
          {
              int d = degree(node->m_children.current());
              if(ret < d)
              {
                  ret = d;
              }
          }
      }
      return ret;
    }
  public:
    GTree()
    {

    }
    //插入結(jié)點(diǎn)
    bool insert(TreeNode<T>* node)
    {
      bool ret = true;
      if(node != NULL)
      {
          //樹為空,插入結(jié)點(diǎn)為根結(jié)點(diǎn)
          if(this->m_root == NULL)
          {
              node->parent = NULL;
              this->m_root = node;
          }
          else
          {
              //找到插入結(jié)點(diǎn)的父結(jié)點(diǎn)
              GTreeNode<T>* np = find(node->parent);
              if(np != NULL)
              {
                  GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);
                  //如果子結(jié)點(diǎn)中無該結(jié)點(diǎn),插入結(jié)點(diǎn)
                  if(np->m_children.find(n) < 0)
                  {
                      ret = np->m_children.insert(n);
                  }
              }
              else
              {
                  THROW_EXCEPTION(InvalidOperationException, "Invalid node...");
              }
          }
      }
      else
      {
          THROW_EXCEPTION(InvalidParameterException, "Parameter is invalid...");
      }
      return ret;
    }
    bool insert(const T& value, TreeNode<T>* parent)
    {
      bool ret = true;
      GTreeNode<T>* node = GTreeNode<T>::NewNode();
      if(node != NULL)
      {
          node->value = value;
          node->parent = parent;
          insert(node);
      }
      else
      {
          THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory...");
      }
      return ret;
    }
    //刪除結(jié)點(diǎn)
    SharedPointer<Tree<T>> remove(const T& value)
    {
      GTree<T>* ret = NULL;
      //找到結(jié)點(diǎn)
      GTreeNode<T>* node = find(value);
      if(node != NULL)
      {
          remove(node, ret);
          m_queue.clear();
      }
      else
      {
          THROW_EXCEPTION(InvalidParameterException, "Parameter invalid...");
      }
      return ret;
    }

    SharedPointer<Tree<T>> remove(TreeNode<T>* node)
    {
      GTree<T>* ret = NULL;
      node = find(node);
      if(node != NULL)
      {
          remove(dynamic_cast<GTreeNode<T>*>(node), ret);
          m_queue.clear();
      }
      else
      {
          THROW_EXCEPTION(InvalidParameterException, "Parameter invalid...");
      }
      return ret;
    }
    //查找結(jié)點(diǎn)
    GTreeNode<T>* find(const T& value)const
    {
      return find(root(), value);
    }
    GTreeNode<T>* find(TreeNode<T>* node)const
    {
        return find(root(), dynamic_cast<GTreeNode<T>*>(node));
    }
    //根結(jié)點(diǎn)訪問函數(shù)
    GTreeNode<T>* root()const
    {
        return dynamic_cast<GTreeNode<T>*>(this->m_root);
    }
    //樹的度訪問函數(shù)
    int degree()const
    {
        return degree(root());
    }
    //樹的高度訪問函數(shù)
    int height()const
    {
        height(root());
    }
    //樹的結(jié)點(diǎn)數(shù)目訪問函數(shù)
    int count()const
    {
        count(root());
    }
    //清空樹
    void clear()
    {
        free(root());
        this->m_root = NULL;
    }

    bool begin()
    {
      bool ret = (root() != NULL);
      if(ret)
      {
          //清空隊列
          m_queue.clear();
          //根節(jié)點(diǎn)加入隊列
          m_queue.add(root());
      }
      return ret;
    }

    bool end()
    {
        return (m_queue.length() == 0);
    }

    bool next()
    {
      bool ret = (m_queue.length() > 0);
      if(ret)
      {
          GTreeNode<T>* node = m_queue.front();
          m_queue.remove();//隊頭元素出隊
          //將隊頭元素的子結(jié)點(diǎn)入隊
          for(node->m_children.move(0); !node->m_children.end(); node->m_children.next())
          {
              m_queue.add(node->m_children.current());
          }
      }
      return ret;
    }

    T current()
    {
      if(!end())
      {
          return m_queue.front()->value;
      }
      else
      {
          THROW_EXCEPTION(InvalidOperationException, "No value at current Node...");
      }
    }
    virtual ~GTree()
    {
      clear();
    }
  };

分享題目:數(shù)據(jù)結(jié)構(gòu)(十三)——樹
文章路徑:http://aaarwkj.com/article4/iijjoe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號服務(wù)器托管、云服務(wù)器、網(wǎng)站改版、外貿(mào)網(wǎng)站建設(shè)、定制開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司
欧美精品在线观看不卡一区| 黄色亚洲一区二区三区四区| 一级片欧美女人性生活片| 精品女厕一区二区三区| 日本啪啪精品一区二区三区 | 久久热在线观看免费高清| 亚洲精品丝袜成人偷拍| 一区二区三区乱码av| 国产男女猛烈无遮挡av| 亚洲av日韩专区在线观看| 九九九热视频这里只有精品| 成人黄色av网站在线观看 | 狠狠久久五月综合色和啪| 97资源视频在线播放| 中文字幕日韩精品在线看| 日本一区二区电影大全| 亚洲av成人噜噜网站| 91九色在线精品一区| 97全国免费观看视频| av小说亚洲激情乱| 好色人妻在线播放中文字幕| 午夜体内射精免费视频| 国产在线高清精品二区| 日韩人妻系列在线观看| 亚洲不卡一区二区在线| 久久五十路六十路熟妇中出| 日本成人在线播放网站| 91九色午夜在线观看| 五月婷婷少妇中文字幕| 黄片大全在线免费视频观看| 亚洲成人免费在线一区| 日韩精品一区二区一牛| 日韩在线中文字幕一区| 亚洲免费视频区一区二| 黑人巨大亚洲一区二区久| 久久精品国产亚洲av麻豆花絮| 视频免费观看网站不卡| 国产又猛又黄又爽无遮挡| 国产精品久久久av大片| 亚洲av色男人天堂网| va精品人妻一区二区三区|