数据结构与算法分析课后习题第四章(3)

4.38 The larger binary trees in this chapter were generated automatically by a program. This was done by assigning an (x,y) coordinate to each tree node, drawing a circle around each coordinate (this is hard to see in come pictures), and connecting each node to its parent. Asume you have a binary search tree stored in memory (perhaps generated by one of the routines above) and that each node has two extra fields to store the coordinates.

a. The x coordinate can be computed by assigning the inorder traversal number. Write a routine to do this for each node in the tree.

b. The y coordinate can be computed by using the negative of the depth of the node. Write a rutine to do this for each node in the tree.

4.39 Write a general-purpose tree-drawing programs that will convert a tree into the following graph-assemler instructions:

a. Circle(X, Y)

b. DrawLine(i, j)

The first instruction draws a circle at (X, Y), and the second instruction connects the ith circle to the jth circle (circles are numbered in the order drawn). You should either make this a program and define some sort of input language or make this a function that can be called from any program.

//4.38 bstree.hpp

#ifndef BSTREE_HPP__
#define BSTREE_HPP__

#include <iosfwd>

const int XIncrement = 5;
const int YIncrement = -10;

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(0), y(0)
  {}

 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);
 }


 
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);
  }
 }

private:
 Node* root;
 Node* parent;

};

#endif

//4.39 bstree.hpp

#ifndef BSTREE_HPP__
#define BSTREE_HPP__

#include <iosfwd>

class DrawTree;

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);
 }

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);
  }
 }

private:
 Node* root;
 Node* parent;

 friend class DrawTree;

};

#endif

//drawtree.hpp

#ifndef DRAWTREE_HPP__
#define DRAWTREE_HPP__

#include <windows.h>

class Point;

template < typename Object >
class BSTree;

const int Radius = 10;

class DrawTree {
public:
 DrawTree();
 ~DrawTree();
 
 void Draw(const HWND&);
 
private:
 void Circle(int, int, const HWND&);
 void DrawLine(const Point&, const Point&, const HWND&);
 
 template< typename Object >
 void DoDraw(const HWND&, const typename BSTree<Object>::Node*);
 DrawTree(const DrawTree&);
 DrawTree& operator=(const DrawTree&);

};

#endif

//treegen.hpp

#ifndef TREEGEN_HPP__
#define TREEGEN_HPP__

#include "bstree.hpp"
#include <cstdlib>
#include <vector>
#include <ctime>

template< typename Object >
void TreeGenerator(BSTree<Object>& tree, const int num)
{
 std::srand(time(NULL));
 std::vector<Object> vec;
 int size = num;
 
 for(int i = 1; i <= num; ++i)
 {
  vec.push_back(i);
 }

 for(int i = 0; i < num; ++i)
 {
  std::vector<Object>::iterator it = vec.begin();
  int n = rand() % (size--);
  it += n;
  tree.add(*it);
  vec.erase(it);
 }
}

#endif

//drawtree.cpp

#include "drawtree.hpp"
#include "treegen.hpp"
#include <cstdlib>

class Point{
public:
 Point(int x = NULL, int y = NULL) : x(x), y(y)
 {}
public:
 int x;
 int y;
};

DrawTree::DrawTree()
{}

DrawTree::~DrawTree()
{}

void DrawTree::Circle(int x, int y, const HWND& hwnd)
{
 HDC hdc = GetDC(hwnd);
 Ellipse(hdc, x-Radius, y-Radius, x+Radius, y+Radius);
}

void DrawTree::DrawLine(const Point &from, const Point &to,
      const HWND& hwnd)
{
 HDC hdc = GetDC(hwnd);
 MoveToEx(hdc, from.x, from.y, NULL);
 LineTo(hdc,to.x, to.y);
}

void DrawTree::Draw(const HWND& hwnd)
{
 BSTree<int> tree;
 TreeGenerator(tree, 30);
 tree.calcXCoordinate();
 tree.calcYCoordinate();

 DoDraw<int>(hwnd, tree.root);
}

template< typename Object >
void DrawTree::DoDraw(const HWND& hwnd, const typename BSTree<Object>::Node* t)
{
 if(t != NULL)
 {
  Circle(t->x, t->y, hwnd);
  if(t->lChild != NULL)
   DrawLine(Point(t->x-Radius, t->y+Radius),
    Point(t->lChild->x+Radius, t->lChild->y-Radius) ,hwnd);
  if(t->rChild != NULL)
   DrawLine(Point(t->x+Radius, t->y+Radius),
    Point(t->rChild->x-Radius, t->rChild->y-Radius) ,hwnd);
  wchar_t a[20];
  _i64tow_s(t->data, a, 20, 10);
  TextOut(GetDC(hwnd), t->x, t->y-Radius/2, a, wcslen(a));
  DoDraw<Object>(hwnd, t->lChild);
  DoDraw<Object>(hwnd, t->rChild);
 }
}

//main.cpp

#include "bstree.hpp"
#include "drawtree.hpp"
#include <windows.h>


LRESULT WINAPI WndProc (HWND, UINT, WPARAM, LPARAM);
//WinMain函数
int WINAPI WinMain (HINSTANCE hInstance,
     HINSTANCE hPrevInstance,
     LPSTR lpCmdLine,
     int nCmdShow)
{
 HWND hWnd; //主窗口句柄
 MSG msg; //窗口消息
 WNDCLASSEX wndcls; //窗口类
 if ( !hPrevInstance )
 {
  //填充窗口类信息
  wndcls.cbSize = sizeof(WNDCLASSEX);
  wndcls.style = CS_HREDRAW | CS_VREDRAW; //当长或宽改变的时候重画整个窗口
  wndcls.lpfnWndProc = WndProc; //长指针指向windows过程处理函数
  wndcls.cbClsExtra = 0; //指明了为windows类额外分配的内存的数量,windows初始化为0
  wndcls.cbWndExtra = 0; //指定了为windows实例额外分配的内存的数量,windows初始化为0
  wndcls.hInstance = hInstance; //指向windows程序实例的句柄
  wndcls.hIcon = LoadIcon(NULL, IDI_APPLICATION); //为了使用预先定义好的图标,需将第一个参数高为NULL
  wndcls.hCursor = LoadCursor(NULL,  IDC_ARROW);
  wndcls.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); //背景的画刷
  wndcls.lpszMenuName = NULL; //菜单
  wndcls.lpszClassName = TEXT("Draw Binary Search Tree"); //指明了windows类的名称
  wndcls.hIconSm = NULL;
  //注册窗口类
  RegisterClassEx(&wndcls);
 }
 //创建应用程序主窗口
 hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
  TEXT("Draw Binary Search Tree"),
  TEXT("Tree graph"),
  WS_OVERLAPPED,
  0,
  0,
  1024,
  768,
  NULL,
  NULL,
  NULL,
  NULL);
 //显示窗口
 ShowWindow(hWnd, SW_SHOW);
 //更新主窗口客户区
 UpdateWindow(hWnd);
 //开始消息循环
 while ( GetMessage(&msg, NULL, 0, 0) )
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 return msg.wParam;
}

//主窗口过程,处理窗口中各种各样的事件
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
 DrawTree* dt;
 switch ( msg )
 {
 case WM_PAINT:
  dt = new DrawTree();
  dt->Draw(hWnd);
  
  break;
 case WM_DESTROY:
  PostQuitMessage(0); //发送退出程序的消息
  break;
 default:
  break;
 }
 return DefWindowProc(hWnd, msg, wParam, lParam);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值