1. 程式人生 > >資料結構與演算法分析課後習題第四章(4)

資料結構與演算法分析課後習題第四章(4)

4.40 Write a routine to list out the nodes of a binary tree in level-order. List the root, then nodes at depth 1, followed by nodes at depth 2, and so on.

4.44 Write a procedure to traverse a tree stored with child/sibling links.

4.49 Since a binary search tree with N nodes has N + 1 NULL pointers, half the space allocated in a binary search tree for pointer information is wasted. Suppose that if a node has a NULL left child, we make its self child link to its inorder predecessor, and if a node has a NULL right child, we make its right child link to its inorder successor. This is known as a threaded thre and the extra links are called threads.

a. How can we distinguish threads from real children pointers?

b. Write routines to perform insertions and deletions into a tree threaded in the manner described above.

c. What is the advantage of using threaded trees?

//4.40 bstree.hpp 

#ifndef BSTREE_HPP__
#define BSTREE_HPP__

#include <iosfwd>
#include <vector>

template< typename Object >
class BSTree;

template< typename Object >
void levelOrderTraverse(const typename BSTree<Object>::Node*);

const int XIncrement = 30;
const int YIncrement = 40;

template< typename Object >
class BSTree {
private:
 class Node {
 public:
  Node(const Object& val = Object(), Node* l = NULL, Node* r = NULL,
   Node* p = NULL) : parent(p), lChild(l),
   rChild(r), data(val), x(10), y(10)
  {}

 public:
  Object data;
  Node* lChild;
  Node* rChild;
  Node* parent;
  int x, y;
 };

public:
 BSTree() : root(NULL), parent(NULL) {}
 ~BSTree(){ clear(); }
 BSTree(const BSTree& rhs){}
 BSTree& operator=(const BSTree& rhs){}

public:
 bool contains(const Object& val) const
 { return contains(val, root); }
 bool empty() const
 { return root == NULL; }
 void printTree(std::ostream& out)
 { 
  if(empty())
   out << "empty tree/n";
  else
   printTree(root, out); 
 }

 void clear()
 { clear(root); }
 void add(const Object& val)
 { insert(val, root, parent); }
 void del(const Object& val)
 { remove(val, root, parent); }
 void calcXCoordinate()
 { 
  int c = 0;
  calcXCoordinate(root, c);
 }
 void calcYCoordinate()
 {
  int c = 0;
  calcYCoordinate(root, c);
 }

 void levelOrderTraverse()
 { levelOrderTraverse(root); }

 void postOrderTraverse()
 { postOrderTraverse(root); }
  
private:
 void insert(const Object& val, Node* &t, Node* &parent)
 {
  if(t == NULL)
   t = new Node(val, NULL, NULL, parent);
  else if(val < t->data)
   insert(val, t->lChild, t);
  else if(t->data < val)
   insert(val, t->rChild, t);
  else
   return;
 }
 
 void remove(const Object& val, Node* &t, Node* &parent)
 {
  if(t == NULL)
   return;

  if(val < t->data)
   remove(val, t->lChild, t);
  else if(t->data < val)
   remove(val, t->rChild, t);
  else if(t->lChild != NULL && t->rChild != NULL)
  {
   t->data = findMin(t->rChild)->data;
   remove(t->data, t->rChild, t);
  }
  else if((t->lChild != NULL && t->rChild == NULL) ||
   (t->lChild == NULL && t->rChild != NULL))
  {
   Node* old = t;
   t = (t->lChild != NULL) ? t->lChild : t->rChild;
   t->parent = old->parent;
   delete old;
  }
  else
  {
   t->parent->rChild == t ? t->parent->rChild = NULL :
         t->parent->lChild = NULL;
   delete t;
  }
 }

 bool contains(const Object& val, Node* t) const
 {
  if(t == NULL)
   return false;
  else if(val < t->data)
   return contains(val, t->lChild);
  else if(t->data < val)
   return contains(val, t->rChild);
  else
   return true;
 }
 
 static Node* findMin(Node* t)
 {
  if(t != NULL)
   while(t->lChild != NULL)
    t = t->lChild;
  return t;
 }

 static Node* findMax(Node* t)
 {
  if(t != NULL)
   while(t->rChild != NULL)
    t = t->rChild;
  return t;
 }

 void clear(Node* &t)
 {
  if(t != NULL)
  {
   clear(t->lChild);
   clear(t->rChild);
   delete t;
  }
  t = NULL;
 }

 void printTree(Node* t, std::ostream& out)
 {
  if(t != NULL)
  {
   printTree(t->lChild, out);
   out << "[ " << t->x << ", "
    << t->y << " ]" << t->data << "/n";
   printTree(t->rChild, out);
  }
 }

 void calcXCoordinate(Node* t, int& count)
 {
  if(t != NULL)
  {
   calcXCoordinate(t->lChild, count);
   t->x += XIncrement * (count++);
   calcXCoordinate(t->rChild, count);
  }
 }

 void calcYCoordinate(Node* t, int count)
 {
  if(t != NULL)
  {
   t->y += YIncrement * (count++);
   calcYCoordinate(t->lChild, count);
   calcYCoordinate(t->rChild, count);
  }
 }

 void levelOrderTraverse(const Node* t)
 {
  if(t != NULL)
  {
   std::cout << t->data << "/n";
   if(!vec.empty())
   {
    vec.push_back(t);
    const Node* p = vec.front();
    vec.erase(vec.begin());
    levelOrderTraverse(p->rChild);
   }
   else
    vec.push_back(t);

   if(t->lChild != NULL && t->rChild != NULL)
   {
    levelOrderTraverse(t->lChild);
   }
   else if(t->lChild != NULL || t->rChild != NULL)
   {
    levelOrderTraverse(t->rChild != NULL ? t->rChild : t->lChild);
   }

  }
 }

 void postOrderTraverse(Node* t)
 {
  if(t != NULL)
  {
   std::cout << t->data << "/n";
   postOrderTraverse(t->lChild);
   postOrderTraverse(t->rChild);
  }
 }

private:
 Node* root;
 Node* parent;
 std::vector< const Node* > vec;

};

#endif

//4.44 tree.hpp

#ifndef TREE_HPP__
#define TREE_HPP__

#include <iosfwd>

template< typename Object >
class Tree {
public:
 class Node {                                                  //haven't write insert routines so keep the Node public
 public:
  Node(const Object d = Object(),
   Node* c = NULL, Node* s = NULL) :
  data(d), child(c), sibling(s)
  {}

 public:
  Node* child;
  Node* sibling;
  Object data;

 };

public:
 Tree(){}
 ~Tree(){}


 void printTree()
 { printTree(root); }
 Node* root;
private:
 void printTree(Node* t)
 {
  if(t != NULL)
  {
   std::cout << t->data << "/n";
   if(t->sibling != NULL)
    printTree(t->sibling);
   if(t->child != NULL)
    printTree(t->child);
  }
 }
 
private:
 Tree(const Tree&);
 Tree& operator=(const Tree&);

};

#endif

//4.49 tbstree.hpp

#ifndef TBSTREE_HPP__
#define TBSTREE_HPP__

#include <iosfwd>

template< typename Object >
class ThreadBSTree {
private:
 class Node {
 public:
  Node(const Object val = Object(), Node* l = NULL,
   Node* r = NULL, bool p = true, bool s = true)
   : data(val), left(l), right(r), pre(p), suc(s)
  {}

  Node(const Node& rhs)
  {
   left = rhs.left;
   right = rhs.right;
   data = rhs.data;
   pre = rhs.pre;
   suc = rhs.suc;
  }

  Node& operator=(const Node& rhs)
  { return Node(rhs); }

 public:
  Node* left;
  Node* right;
  bool pre;
  bool suc;
  Object data;

 };

public:
 class iterator {
 public:
  iterator() : current(NULL)
  {}

  Object& operator*()
  { return current->data; }
  const Object& operator*() const
  { return current->data; }

  const iterator& operator++()
  {
   if(current->suc)
   {
    current = current->right;
    return current;
   }
   else
    return current = findMin(current->right);
  }

  iterator operator++(int)
  {
   iterator old = *this;
   ++(*this);
   return old;
  }

  const iterator& operator--()
  {
   if(current->pre)
    return current = current->left;
   else
    return current = findMax(current->left);
  }

  iterator operator--(int)
  {
   iterator old = *this;
   --(*this);
   return old;
  }

  bool operator==(const iterator& rhs) const
  { return current == rhs.current; }
  bool operator!=(const iterator& rhs) const
  { return !(rhs == *this); }

 private:
  Node* current;
  iterator(Node* c) : current(c)
  {}

  friend class ThreadBSTree;

 };

public:

 ThreadBSTree() : root(NULL)
 {}
 ~ThreadBSTree()
 { clear(); }

 iterator begin()
 { return iterator(findMin(root)); }
 const iterator begin() const
 { return iterator(findMin(root)); }

 iterator end()
 { return iterator(NULL); }
 const iterator end() const
 { return iterator(NULL); }

 bool empty() const
 { return root == NULL; }

 void insert(const Object val)
 { insert(val, root); }

 void erase(const Object val)
 { erase(val, root); }

 void printTree()
 { printTree(root); }

 void clear()
 { clear(root); }


private:
 static Node* findMin(Node* t)
 {
  while(t != NULL && t->pre == false)
   while(t->left != NULL && t->pre == false)
    t = t->left;
  return t;
 }

 static Node* findMax(Node* t)
 {
  while(t != NULL && t->suc == false)
   while(t->right != NULL  && t->suc == false)
    t = t->right;
  return t;
 }

 void clear(Node* &t)
 {
  if(t != NULL)
  {
   clear(t->left);
   clear(t->right);
   delete t;
  }
  t = NULL;
 }

 void insert(const Object val, Node* &t, bool pre = true, bool suc = true)
 {
  if(t == NULL)
   t = new Node(val, NULL, NULL, pre, suc);
  else if(t->data < val)
  {
   Node* old = t->right;
   t->right = (t->suc == true ? NULL : t->right);
   insert(val, t->right);
   if(t->suc)
   {
    t->suc = false;
    t->right->left = t;
    t->right->right = old;
   }
  }
  else if(val < t->data)
  {
   Node* old = t->left;
   t->left = (t->pre == true ? NULL : t->left);
   insert(val, t->left);
   if(t->pre)
   {
    t->pre= false;  
    t->left->right = t;
    t->left->left = old;
   }
  }
  else
   ;
 }

 void erase(const Object& val, Node* &t)
 {
  if(t == NULL)
   return;

  if(val < t->data)
  {
   if(!t->pre)
   {
    erase(val, t->left);
   }
   return;
  }
  else if(t->data < val)
  {
   if(!t->suc)
    erase(val, t->right);
   return;
  }
  else if((t->pre == false && t->left != NULL) &&
   (t->suc == false && t->right != NULL))
  {
   t->data = findMin(t->right)->data;
   erase(t->data, t->right);
  }
  else
  {
   Node* old = t;
   if(t->pre == true && t->suc == false)
   {
    if(t->left->right == t)   //right-right case
     t->left->right = t->right;
    else       //left-right case
     findMax(t->right)->right->left = t->right;
    t = t->right;
   }
   else if(t->pre == false && t->suc == true)
   {
    if(t->right->left == t)   //left-left case
     t->right->left = t->left;
    else       //right-left case
     findMin(t->left)->left->right = t->left;

    t = t->left;
   }
   else
   {
    if(t->left != NULL && t->left->right == t)  //right sub-tree case
    {
     t->left->suc = true;
     t->left->right = t->right;
    }
    else if(t->right != NULL && t->right->left == t) //left sub-tree case
    {
     t->right->pre = true;
     t->right->left = t->left;
    }
   }
   delete old;
  }
 }


 void printTree(Node* t)
 { 
  if(t != NULL)
  {
   if(!t->pre)
    printTree(t->left);
   std::cout << t->data << "/n";
   if(!t->suc)
    printTree(t->right);
  }
 }
private:
 Node* root;

};

#endif