樹是一種非線性的數(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)的子樹。
樹的示例如下:
成都創(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ù)。
樹的結(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)中度的最大值。
結(jié)點(diǎn)的直接后繼稱為結(jié)點(diǎn)的孩子,結(jié)點(diǎn)稱為孩子的雙親。
結(jié)點(diǎn)的孩子的孩子稱為結(jié)點(diǎn)的孫子,結(jié)點(diǎn)稱為子孫的祖先。
同一個雙親的孩子之間互稱兄弟。
樹中根結(jié)點(diǎn)為第1層,根結(jié)點(diǎn)的孩子為第2層,依次類推。
樹中結(jié)點(diǎn)的最大層次稱為樹的深度或高度
如果樹中結(jié)點(diǎn)的各子樹從左向右是有序的,子樹間不能互換位置,則稱該樹為有序樹,否則為無序樹。
森林是由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;
};
樹中的結(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()
{
}
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:
};
每個樹結(jié)點(diǎn)包含指向前驅(qū)結(jié)點(diǎn)的指針,優(yōu)點(diǎn)在于可以將非線性的樹轉(zhuǎn)化為線性的結(jié)構(gòu)。
A、基于數(shù)據(jù)元素值的查找
定義在任意一個結(jié)點(diǎn)為根結(jié)點(diǎn)的樹中查找指定數(shù)據(jù)元素值所在的結(jié)點(diǎn)的函數(shù)。
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ù)
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));
}
樹是非線性的數(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)的流程
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ù)元素到樹中的流程如下:
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)清除,并釋放分配在堆中的結(jié)點(diǎn)。
定義清除樹中每個結(jié)點(diǎn)的函數(shù)
如果樹中的結(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;
}
刪除函數(shù)的設(shè)計要點(diǎn):
將被刪除結(jié)點(diǎn)的子樹進(jìn)行刪除;
刪除函數(shù)返回一顆堆空間的樹;
具體返回值為指向樹的智能指針;
具體的結(jié)點(diǎn)刪除功能函數(shù)如下:
將node為根結(jié)點(diǎn)的子樹從原來的樹中刪除,ret作為子樹返回
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;
}
A、樹中結(jié)點(diǎn)的數(shù)量
以node為結(jié)點(diǎn)的子樹的結(jié)點(diǎn)數(shù)量,遞歸模型如下:
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ù)的遞歸模型如下:
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ù)的遞歸模型如下:
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());
}
樹是一種非線性的數(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)
將根結(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...");
}
}
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;
}
};
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)