#include "Box.h"
#include <afxtempl.h>
typedef CTypedPtrList<CObList , CBox*> CBoxList;
typedef CTypedPtrMap <CMapStringToPtr, CString, int*> CRecords;
struct BinarySearchTreeNode{
CBox * data ;
BinarySearchTreeNode *leftChild; //左子节点, 左框
BinarySearchTreeNode *rightChild; //右子节点,右框
BinarySearchTreeNode *InChild; //三叉节点,也是中梃节点
BinarySearchTreeNode *ParentChild; //前驱节点
BinarySearchTreeNode(CBox* tempdata)
{ data = tempdata;
leftChild = NULL;
rightChild = NULL;
InChild = NULL; //三叉节点,也是中梃节点
ParentChild = NULL; //前驱节点
}
};
///
// BinarySearchTree command target
class BinarySearchTree : public CCmdTarget
{
DECLARE_SERIAL(BinarySearchTree)
BinarySearchTree();
virtual ~BinarySearchTree();
protected:
BinarySearchTreeNode * Root;
public:
CBoxList* ml;
CRecords* pRecords;
public:
BinarySearchTreeNode *GetRoot() {return this->Root;}
void SetRoot(BinarySearchTreeNode * p) {this->Root = p;}
//绘图图形
void OnDraw (BinarySearchTreeNode * tempRoot , CDC * pDC )
{
//这里是绘制一个节点内的框
GetBoxToNode (tempRoot) ->OnDraw(pDC);
}
/**********************************************************
*参数1:当前子树根节点
*参数2:函数指针
*参数3:备用指针
*返回值:空
*功能:前序遍历二叉查找树
************************************************************/
void PreOrderBSTPrint(BinarySearchTreeNode * tempRoot , CDC * pDC)
{
if(NULL==tempRoot) return ;
OnDraw(tempRoot,pDC);
//如果有中梃, 就绘制它
if(tempRoot->InChild)
{
OnDraw(tempRoot->InChild,pDC);
}
PreOrderBSTPrint(tempRoot->leftChild , pDC);
PreOrderBSTPrint(tempRoot->rightChild , pDC);
}
BOOL InsertBST(BinarySearchTreeNode * tempRoot , CPoint tempPt , UINT iType)
{
BinarySearchTreeNode* p = NULL;
SeletedToNode(tempRoot ,tempPt , &p);
if (p)
{
CreateToNode(p , tempPt ,iType);
return TRUE ;
}
else return FALSE;
}
void SetIsSeleted(BinarySearchTreeNode *tempRoot , CPoint pt)
{
//在这里要清除所有选中状态
UnsetSeleted(tempRoot);
BinarySearchTreeNode* p = NULL;
SeletedToNode(tempRoot , pt , &p);
if(p)
{
CBox* m = GetBoxToNode(p);
m->SetSeleced();
}
}
void SeletedToNode(BinarySearchTreeNode *tempRoot, CPoint pt , BinarySearchTreeNode **p)
{
if(NULL==tempRoot) return ;
CBox * p0 = GetBoxToNode(tempRoot) ;
CRect rtmp0 = p0->GetBox() ;
if( rtmp0.PtInRect(pt) && !tempRoot->leftChild && !tempRoot->rightChild)
{
*p = tempRoot;
return ;
}
if(tempRoot->InChild)
{
CBox * p2 = GetBoxToNode(tempRoot->InChild) ;
CRect rtmp2 = p2->GetBox() ;
if( rtmp2.PtInRect(pt))
{
*p = tempRoot->InChild;
return ;
}
}
if(tempRoot->leftChild)
SeletedToNode(tempRoot->leftChild, pt , p);
if(tempRoot->rightChild)
SeletedToNode(tempRoot->rightChild , pt, p);
}
void UpDataToSet(BinarySearchTreeNode *tempRoot, set<int>& x , set<int>& y)
{
if(NULL==tempRoot) return ;
//如果是根节点
if( tempRoot == Root)
{
//先清除set
x.clear();
y.clear();
//把左和右插入set
CBox * p0 = GetBoxToNode(tempRoot) ;
CRect rtmp0 = p0->GetBox() ;
x.insert((int)rtmp0.left);
x.insert((int)rtmp0.right);
y.insert((int)rtmp0.top);
y.insert((int)rtmp0.bottom);
}
else
{
if(tempRoot->InChild )
{
CBox * p2 = GetBoxToNode(tempRoot->InChild) ;
UINT i = p2->GetToType();
if(i == 2)
{
CRect rtmp2 = p2->GetBox() ;
CPoint pt2 = rtmp2.CenterPoint();
x.insert((int)pt2.x);
}
if(i == 12)
{
CRect rtmp12 = p2->GetBox() ;
CPoint pt12 = rtmp12.CenterPoint();
y.insert((int)pt12.y);
}
}
}
if(tempRoot->leftChild)
UpDataToSet(tempRoot->leftChild, x , y);
if(tempRoot->rightChild)
UpDataToSet(tempRoot->rightChild , x , y);
}
//创建一个节点
BOOL CreateToNode(BinarySearchTreeNode *temp , CPoint pt , UINT iType)
{
if(NULL==temp)
return FALSE;
else
{
//1. 把父节点传进来
//2. 创建三个节点 分别为父节点的三个子节点
//3. 把指针都连接起来
int v = 10;
if(pRecords)
{
int *mx= NULL ;
pRecords->Lookup("中梃小面", mx);
v= *mx ;
}
CBox* m0 = GetBoxToNode(temp);
CRect p0 = m0->GetBox();//为父框
if(2 == iType)
{
CRect* p1 = new CRect(p0.left,p0.top,pt.x-v/2,p0.bottom);
CBox* m1 = new CBox(p1);
BinarySearchTreeNode* n1 = new BinarySearchTreeNode (m1);
temp->leftChild = n1;
n1->ParentChild = temp ;
CRect* p2 = new CRect(pt.x-v/2,p0.top,pt.x+v/2,p0.bottom);
CBox* m2 = new CBox(p2);
m2->SetToType(iType);
BinarySearchTreeNode* n2 = new BinarySearchTreeNode (m2);
temp->InChild = n2;
n2->ParentChild = temp ;
CRect* p3 = new CRect(pt.x+v/2,p0.top,p0.right,p0.bottom);
CBox* m3 = new CBox(p3);
BinarySearchTreeNode* n3 = new BinarySearchTreeNode (m3);
temp->rightChild = n3;
n3->ParentChild = temp ;
}
if(12 == iType)
{
//CBox* m0 = GetBoxToNode(temp);
//CRect p0 = m0->GetBox();//为父框
CRect* p1 = new CRect(p0.left,p0.top,p0.right , pt.y-v/2);
CBox* m1 = new CBox(p1);
BinarySearchTreeNode* n1 = new BinarySearchTreeNode (m1);
temp->leftChild = n1;
n1->ParentChild = temp ;
CRect* p2 = new CRect(p0.left,pt.y-v/2,p0.right,pt.y+v/2);
CBox* m2 = new CBox(p2);
m2->SetToType(iType);
BinarySearchTreeNode* n2 = new BinarySearchTreeNode (m2);
temp->InChild = n2;
n2->ParentChild = temp ;
CRect* p3 = new CRect(p0.left,pt.y+v/2,p0.right,p0.bottom);
CBox* m3 = new CBox(p3);
BinarySearchTreeNode* n3 = new BinarySearchTreeNode (m3);
temp->rightChild = n3;
n3->ParentChild = temp ;
}
m0->SetToType(0);
}
return TRUE ;
}
/**********************************************************
*功能:取得一个RECT
*参数:节点
*返回值:RECT
************************************************************/
CRect* GetRectToNode(BinarySearchTreeNode *p )
{
if(p)
{
CBox * pb = (CBox *)p->data ;
return & pb->GetBox() ;
}
else return NULL;
}
void MoveToNode(BinarySearchTreeNode *tempRoot , int value)
{
if(tempRoot)
{
//开始操作中梃节点
CBox* b0 = GetBoxToNode(tempRoot);
CRect r0 = b0->GetBox();
UINT s = b0->GetToType() ;
if (2 == s)
{
r0.left += value;
r0.right += value;
b0->SetBox(r0);//为父框
}
if (12 == s)
{
r0.top += value;
r0.bottom += value;
b0->SetBox(r0);//为父框
}
//4. 更新所有节点的左节点的数据和右节点的数据
PreOrderBST(Root, 4);
}
}
void DeletedToNode(BinarySearchTreeNode *tempRoot)
{
if(tempRoot)
{
CBox* i = NULL ;
CBox* l = NULL ;
CBox* r = NULL;
//这是左右节点都无子节情况删除
if(!tempRoot->ParentChild->leftChild->InChild && !tempRoot->ParentChild->rightChild->InChild)
{
i = GetBoxToNode(tempRoot->ParentChild->InChild);
l = GetBoxToNode(tempRoot->ParentChild->leftChild);
r = GetBoxToNode(tempRoot->ParentChild->rightChild);
tempRoot->ParentChild->InChild = NULL;
tempRoot->ParentChild->leftChild = NULL;
tempRoot->ParentChild->rightChild = NULL;
delete i ;
delete l ;
delete r ;
}
}
}
void OperateToNode(BinarySearchTreeNode *tempRoot , CPoint tempPt , int ModifyNum , int operNum)
{
if(tempRoot)
{
//1. 先取得选中的节点
BinarySearchTreeNode* p = NULL ;
SeletedToNode(tempRoot ,tempPt , &p);
//是否是中梃节点
if(p && p != Root && p != Root->leftChild )
{
//如果选中的是左节点或右节点直接返回
if (p == p->ParentChild->leftChild || p == p->ParentChild->rightChild )
{
//设置框状态
if(5 == operNum)
{
CBox* pA =GetBoxToNode (p);
pA->SetToType(5);
}
//设置框状态
if(6 == operNum)
{
CBox* pB =GetBoxToNode (p);
pB->SetToType(6);
}
//设置框状态
if(7 == operNum)
{
CBox* pC =GetBoxToNode (p);
pC->SetToType(7);
}
return;
}
//修改
if(75 == operNum)
MoveToNode (p->ParentChild->InChild , ModifyNum);
//删除
if(76 == operNum)
DeletedToNode (p->ParentChild->InChild );
}
}
}
void UpdateLR(BinarySearchTreeNode* tempRoot)
{
if (tempRoot != Root)
{
if(tempRoot && tempRoot->InChild && tempRoot->leftChild && tempRoot->rightChild)
{
//取得父节点框
CBox* b0 = GetBoxToNode(tempRoot);
CRect r0 = b0->GetBox();
//取得中梃节点框
CBox* b2 = GetBoxToNode(tempRoot->InChild);
CRect r2 = b2->GetBox();
UINT s = b2 ->GetToType();
if(2 ==s)
{ //取得左框
CBox* b1 = GetBoxToNode(tempRoot->leftChild);
CRect r1 = b1->GetBox();
r1.top = r0.top;
r1.bottom = r0.bottom;
r1.left = r0.left;
r1.right = r2.left;
//把修改好的RECT再写回去
b1->SetBox(r1);//为父框
CBox* b2 = GetBoxToNode(tempRoot->InChild);
CRect r2 = b2->GetBox();
r2.top = r0.top;
r2.bottom = r0.bottom;
//把修改好的RECT再写回去
b2->SetBox(r2);//为父框
//取得右框//
CBox* b3 = GetBoxToNode(tempRoot->rightChild);
CRect r3 = b3->GetBox();
r3.top = r0.top;
r3.bottom = r0.bottom;
r3.left = r2.right;
r3.right =r0.right;
//把修改好的RECT再写回去
b3->SetBox(r3);//为父框
}
if(12 ==s)
{ //取得左框
CBox* b1 = GetBoxToNode(tempRoot->leftChild);
CRect r1 = b1->GetBox();
//r1.NormalizeRect();
r1.left = r0.left;
r1.right = r0.right;
r1.top = r0.top;
r1.bottom = r2.top;
//把修改好的RECT再写回去
b1->SetBox(r1);//为父框
//取得右框//
CBox* b2 = GetBoxToNode(tempRoot->InChild);
CRect r2 = b2->GetBox();
r2.left = r0.left;
r2.right = r0.right;
//r2.top = r0.bottom;
//r2.bottom =r0.bottom;
//把修改好的RECT再写回去
b2->SetBox(r2);//为父框
//取得右框//
CBox* b3 = GetBoxToNode(tempRoot->rightChild);
CRect r3 = b3->GetBox();
r3.left = r0.left;
r3.right = r0.right;
r3.top = r2.bottom;
r3.bottom =r0.bottom;
//把修改好的RECT再写回去
b3->SetBox(r3);//为父框
}
}
}
}
CBox* GetBoxToNode(BinarySearchTreeNode *p )
{
if(p)
{
CBox * pb = (CBox *)p->data ;
return pb ;
}
else return NULL;
}
void UnsetSeleted(BinarySearchTreeNode *tempRoot)
{
if(NULL==tempRoot)
return ;
//清除本体选中状态
BinarySearchTreeNode* p = tempRoot;
CBox* m = GetBoxToNode(p);
m->UnSeleced();
//清除中梃选中状态
if(p->InChild)
{
CBox* n = GetBoxToNode(p->InChild);
n->UnSeleced();
}
UnsetSeleted(tempRoot->leftChild );
UnsetSeleted(tempRoot->rightChild);
}
void BSTSerialize(BinarySearchTreeNode *tempRoot)
{
//Serialize(CArchive& ar)
if(NULL==tempRoot)
return ;
if(tempRoot)
{
CBox* p1 = GetBoxToNode(tempRoot);
ml->AddTail(p1);
if(tempRoot->InChild)
{
CBox* p1 = GetBoxToNode(tempRoot->InChild);
ml->AddTail(p1);
}
}
BSTSerialize(tempRoot->leftChild );
BSTSerialize(tempRoot->rightChild );
}
//**********************************************************
void PreOrderBST(BinarySearchTreeNode* tempRoot, int i)
{
if(NULL==tempRoot)
return ;
//查询i值,再执行对应的分支函数
switch (i)
{
case 0: Test(tempRoot);break;
case 1:break;
case 2:break;
case 3:break;
case 4: UpdateLR(tempRoot);break;
//case 100: BSTSerialize(tempRoot);
default: break;
}
PreOrderBST(tempRoot->leftChild, i);
PreOrderBST(tempRoot->rightChild, i);
}
/
.cpp
IMPLEMENT_SERIAL(BinarySearchTree, CCmdTarget,1)
BinarySearchTree::BinarySearchTree()
{
EnableAutomation();
Root=NULL;
}