Non-Binary Trees
Non-Binary (General) Tree
- General Tree : Any number of child
- ADT
每个节点记忆了它的第一个孩子和右边的节点
template <class Elem> class GTNode {
public:
GTNode(const Elem&); // Constructor
~GTNode(); // Destructor
Elem value(); // Return value
bool isLeaf(); // TRUE if is a leaf
GTNode* leftmost_child(); // First child
GTNode* right_sibling(); // Right sibling
void setValue(Elem&); // Set value
void insert_first(GTNode<Elem>* n);
void insert_next(GTNright_sibling(); // Right sibling
void remove_first(); // Remove first child
void remove_next(); // Remove sibling
}
template <class Elem> class GenTree {
private:
void printhelp(GTNode*); // Print helper function
public:
GenTree(); // Constructor
~GenTree(); // Destructor
void clear(); // Send nodes to free store
GTNode* root(); // Return the root
void newroot(ELEM, GTnode *, GTnode *); // Combine two subtrees
void print(); // Print a tree
};
- Traversal 1
template<class Elem>
void GenTree<Elem> ::printhelp(GTNode<Elem> * subroot){
if(subroot->isLeaf()) cout<<"Leaf : ";
else cout<<"Internal : ";
cout<<subroot->value()<<"\n";
for(GTNode<Elem>* temp=subroot->leftmost_child();
temp!=NULL;
temp=temp->right_sibling())
printhelp(temp);
//顺序 :先一直向左,走到头以后再考虑去右边的节点
//相当于前序遍历
}
- Traversal 2
template<class Elem>
void GenTree<Elem>::printhelp(GTNode<Elem>* subroot){
if(subroot==NULL) return;
if(subroot->isLeaf()) cout<<"Leaf: ";
else cout<<"Internal: ";
cout<<subroot->value()<<"\n";
printhelp(subroot->leftmost_child);
printhelp(subroot->right_sibling);
//和上面的顺序相同
}
Parent Pointer Implementation
- Only storing pointer
- Equivalence Class
- A ↔ B + B ↔ C = A ↔ C A\leftrightarrow B + B\leftrightarrow C = A\leftrightarrow C A↔B+B↔C=A↔C
- UNION/FIND implementation
- Check if two objects are equivalent:
DIFFER
- Set “two objects are equivalent”:
UNION
- Check if two objects are equivalent:
- ADT
用一个数组储存子节点和父节点的对应关系(子节点指向父节点)
class Gentree {
// Gentree for UNION/FIND
private:
int* array; // Node array
int size; // Size of node array
int FIND(int) const; // Find root
public:
Gentree(int); // Constructor
~Gentree() {
delete [] array; } // Destructor
void UNION (int, int); // Merge equivalences
void differ (int, int); // TRUE if not in same tree
}
int Gentree::FIND(int curr) const {
while (array[curr]!=ROOT) curr = array[curr]; //一直往上找 找到根节点
return curr; // At root
}
// Return TRUE if nodes in different trees
//根节点不相同 表示不是同一个树
bool Gentree::differ(int a, int b) {
int root1 = FIND(a); // Find root for a
int root2 = FIND(b); // Find root for b
return root1 != root2; // Compare roots
}
//如果不是同一个树,则后面的树的根节点指向前一个树的根节点(归并操作)
void Gentree::UNION(int a, int b) {
int root1 = FIND(a); // Find root for a
int root2 = FIND(b); // Find root for b
if (root1 != root2) array[root2] = root1;
}
- Example
更新时如果当前节点没有父节点就直接给当前节点添加对应的父节点,否则当前节点的父节点指向该节点,如果有就一直向上找。如果被指节点有父节点,则最后直接在空位更新为被指节点的父节点。
- Reduce the cost
- Weighted Union Rule :Join the tree with fewer nodes to the tree with more nodes
- Path Compression
这个是在寻找的过程中就把路过的每一个节点都优化了int Gentree::FIND(int curr) const { if (array[curr] == ROOT) return curr; return array[curr] = FIND(array[curr]); }
List of Children Implementation
每个节点要储存的值 : index, 自己本身的值, 父节点的index,以及两个指针(父节点指向自己和自己指向自己的邻居)
Left-Child/Right-Sibling Implementation
每个节点要储存的值 : index, 自己本身的值, 父节点和邻居节点的index
Dynamic Left-Child/Right-Sibling Implementation
每个节点要储存的值 :自己的值,指向子节点的指针,指向邻居的指针
Dynamic Node Implementation
每个节点要储存的值 :自己的值,总节点个数,指向自己的指针
每个节点要储存的值 :自己的值,自己指向指针域的指针,指针域(两个指针)
K-ary Trees
- Definition
- Implementation
- Preorder traversal is used
- A / B C / / D E / F / / H I / / J /
空指针用\
表示
- A’ / B’ C D’ E’ / F H’ I J
中间节点加'
,空指针用\
表示,叶子结点的空指针不用表示
Sequential Tree Implementation
)
indicates when a node’s child list has come to an end.