?? graphic.cpp
字號:
#include "stdafx.h"
#include "queue.h"
Graphic::Graphic()
{
//構造函數對圖進行初始化
m_verqueue = NULL;
m_narc = 0;
m_nver = 0;
m_nvisit = 0;
m_nunit = 0;
}
void Graphic::InsertArc(VerNode* pnode,VerNode* pend,int mark)
{
//INSERTARC函數實現在pnode和pend之間插入一條弧
ArcNode* pnew = (ArcNode*)new ArcNode;
pnew->m_padjver = pend;
pnew->m_pnextarc = NULL;
pnew->info = mark;
if(pnode->m_pfirstarc == NULL){
pnode->m_pfirstarc = pnew;
m_narc++;
}
else{
for(ArcNode* p = pnode->m_pfirstarc;p->m_pnextarc;p = p->m_pnextarc){}
p->m_pnextarc = pnew;
m_narc++;
}
}
BOOL Graphic::IsNewArc(VerNode* pnode,VerNode* pend)
{
//判斷pnode和pend之間是否已存在一條弧
for(ArcNode* p = pnode->m_pfirstarc;p;p = p->m_pnextarc){
if(p->m_padjver == pend)
return FALSE;
}
return TRUE;
}
CPoint Graphic::ChagetoPoint(CRect rect)
{
//實現結點所占據的矩形到點的轉變
CPoint point;
point.x = (rect.left+rect.right)/2;
point.y = (rect.bottom+rect.top)/2;
return point;
}
void Graphic::DisplayGraph(CDC* pdc,int type)
{
//在視圖上顯示圖的結構
ArcNode* parc;
CPoint point1,point2;
pdc->SelectStockObject(BLACK_BRUSH);
for(VerNode* pver = m_verqueue->m_phead;pver;pver = pver->m_pnextver){
pdc->Ellipse(pver->m_rect);
point1 = ChagetoPoint(pver->m_rect);
for(parc = pver->m_pfirstarc;parc;parc = parc->m_pnextarc){
pdc->MoveTo(point1);
point2 = ChagetoPoint(parc->m_padjver->m_rect);
pdc->LineTo(point2);
if(type == 0){
pdc->MoveTo(point2);
pdc->LineTo(XL(point1.x,point1.y,point2.x,point2.y),
YL(point1.x,point1.y,point2.x,point2.y));
pdc->MoveTo(point2);
pdc->LineTo(XR(point1.x,point1.y,point2.x,point2.y),
YR(point1.x,point1.y,point2.x,point2.y));
pdc->MoveTo(XL(point1.x,point1.y,point2.x,point2.y),
YL(point1.x,point1.y,point2.x,point2.y));
pdc->LineTo(XR(point1.x,point1.y,point2.x,point2.y),
YR(point1.x,point1.y,point2.x,point2.y));
}
}
}
pdc->SelectStockObject(WHITE_BRUSH);
}
void Graphic::DeleteVer(VerNode* pnode)
{
//刪除pnode所指的結點
VerNode* ptemp;
ArcNode* parc,*parctemp = NULL;
int arc = 0;
for(ptemp = m_verqueue->m_phead;ptemp;ptemp = ptemp->m_pnextver){
for(parc = ptemp->m_pfirstarc;parc;parc = parc->m_pnextarc){
if(parc->m_padjver == pnode){
parctemp = parc;
arc++;
}
}
if(parctemp != NULL)
DeleteArc(ptemp,parctemp);
parctemp = NULL;
}
m_narc = m_narc-GetArcNum(pnode)-arc;
m_verqueue->m_phead = m_verqueue->DeleteVer(pnode);
}
void Graphic::DeleteArc(VerNode* pver,ArcNode* parc)
{
//刪除以pver為頭到parc所指的鄰接結點之間的弧
ArcNode* ptemp = pver->m_pfirstarc;
if(parc == pver->m_pfirstarc){
pver->m_pfirstarc = pver->m_pfirstarc->m_pnextarc;
}
else{
for(;ptemp->m_pnextarc !=parc;ptemp = ptemp->m_pnextarc){}
ptemp->m_pnextarc = parc->m_pnextarc;
delete parc;
}
}
int Graphic::GetArcNum(VerNode* pver)
{
//獲得圖中弧的個數
int n = 0;
for(ArcNode* parc = pver->m_pfirstarc;parc;parc = parc->m_pnextarc){
n++;
}
return n;
}
void Graphic::DeleteArc(VerNode* pstart,VerNode* pend)
{
//刪除pstart和pend所指結點之間的弧
VerNode* start = pstart,* end = pend;
ArcNode* arc = NULL,* temp = NULL;
for(arc = start->m_pfirstarc;arc;arc = arc->m_pnextarc){
if(arc->m_padjver == pend){
temp = arc;
m_narc--;
}
}
if(temp != NULL)
DeleteArc(pstart,temp);
}
VerNode* Graphic::NameToPointer(CString name)
{
//由結點的名字獲得它的指針
VerNode* vertex = NULL;
for(vertex = m_verqueue->m_phead;vertex;vertex = vertex->m_pnextver){
if(vertex->m_strname == name)
break;
}
return vertex;
}
int Graphic::CalculateDu(VerNode* pver)
{
//計算結點pver的度數
VerNode* ver;
ArcNode* arc;
int count = 0;
for(ver = m_verqueue->m_phead;ver;ver = ver->m_pnextver){
for(arc = ver->m_pfirstarc;arc;arc = arc->m_pnextarc){
if(arc->m_padjver == pver)count++;
}
}
for(arc = pver->m_pfirstarc;arc;arc = arc->m_pnextarc)count++;
return count/2;
}
void Graphic::DFSTraverse(CDC* pdc)
{
//DFS深度優先搜索函數
//用于一次顯示所有的結點
CPen pen(PS_DASHDOTDOT,2,RGB(255,0,0));
pdc->SelectObject(&pen);
for(VerNode* pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver)
pnode->m_bvisit = FALSE;
m_nvisit = 0;
m_nunit = 0;
for(pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver){
if(!pnode->m_bvisit){
DFS(pnode,pdc);
m_nunit++;
}
}
pdc->SelectStockObject(BLACK_PEN);
}
void Graphic::DFS(VerNode* pnode,CDC* pdc)
{
//DFS遞歸實現函數
CString str;
m_nvisit++;
pnode->m_bvisit = TRUE;
str.Format("%d",m_nvisit);
pdc->Ellipse(pnode->m_rect.left-5,pnode->m_rect.top-5,
pnode->m_rect.right+5,pnode->m_rect.bottom+5);
pdc->TextOut(pnode->m_rect.left,pnode->m_rect.top-3,str);
for(ArcNode* parc = pnode->m_pfirstarc;parc;parc = parc->m_pnextarc){
VerNode* padj = parc->m_padjver;
if(!padj->m_bvisit)
DFS(padj,pdc);
}
}
void Graphic::DFSTraverse()
{
//DFS深度優先搜索
//用于實現逐步顯示
for(VerNode* pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver)
pnode->m_bvisit = FALSE;
m_nvisit = 0;
m_nunit = 0;
for(pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver){
if(!pnode->m_bvisit){
DFS(pnode);
m_nunit++;
}
}
}
void Graphic::DFS(VerNode* pnode)
{
//DFS深度優先遞歸函數
//用于實現逐步顯示
pnode->m_bvisit = TRUE;
m_nvisit++;
pnode->m_nvisit = m_nvisit;
for(ArcNode* parc = pnode->m_pfirstarc;parc;parc = parc->m_pnextarc){
VerNode* padj = parc->m_padjver;
if(!padj->m_bvisit)
DFS(padj);
}
}
void Graphic::BFSTraverse()
{
//BFS廣度優先搜索
//用于逐步顯示搜索的過程
VerQueue queue;
VerNode pnode1;
for(VerNode* pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver){
pnode->m_bvisit = FALSE;
}
m_nvisit = 0;
for(pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver){
if(!pnode->m_bvisit){
m_nvisit++;
pnode->m_bvisit = TRUE;
pnode->m_nvisit = m_nvisit;
queue.EnQueue(*pnode);
while(queue.m_nnum){
queue.DeQueue(pnode1);
for(ArcNode* parc = pnode1.m_pfirstarc;parc;parc = parc->m_pnextarc){
if(!parc->m_padjver->m_bvisit)
{
m_nvisit++;
parc->m_padjver->m_bvisit = TRUE;
parc->m_padjver->m_nvisit = m_nvisit;
queue.EnQueue(*parc->m_padjver);
} //inner if
} //inner for
} //while
} //outer if
} //outer for
}
void Graphic::BFSTraverse(CDC* pdc)
{
//BFS廣度優先搜索
//用于實現一次性顯示廣度優先搜索的過程
CPen pen(PS_DASHDOTDOT,2,RGB(255,0,0));
pdc->SelectObject(&pen);
VerQueue queue;
VerNode pnode1;
CString str;
for(VerNode* pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver){
pnode->m_bvisit = FALSE;
}
m_nvisit = 0;
for(pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver){
if(!pnode->m_bvisit){
m_nvisit++;
pnode->m_bvisit = TRUE;
str.Format("%d",m_nvisit);
pdc->Ellipse(pnode->m_rect.left-5,pnode->m_rect.top-5,
pnode->m_rect.right+5,pnode->m_rect.bottom+5);
pdc->TextOut(pnode->m_rect.left,pnode->m_rect.top-3,str);
queue.EnQueue(*pnode);
while(queue.m_nnum){
queue.DeQueue(pnode1);
for(ArcNode* parc = pnode1.m_pfirstarc;parc;parc = parc->m_pnextarc){
if(!parc->m_padjver->m_bvisit)
{
m_nvisit++;
parc->m_padjver->m_bvisit = TRUE;
str.Format("%d",m_nvisit);
pdc->Ellipse(parc->m_padjver->m_rect.left-5,
parc->m_padjver->m_rect.top-5,
parc->m_padjver->m_rect.right+5,
parc->m_padjver->m_rect.bottom+5);
pdc->TextOut(parc->m_padjver->m_rect.left,
parc->m_padjver->m_rect.top-3,str);
queue.EnQueue(*parc->m_padjver);
} //inner if
} //inner for
} //while
} //outer if
} //outer for
pdc->SelectStockObject(BLACK_PEN);
}
int Graphic::CalculateInDu(VerNode* pver)
{
//對于有向圖計算它的入度
int count = 0;
for(VerNode* ver = m_verqueue->m_phead;ver;ver = ver->m_pnextver){
for(ArcNode* arc = ver->m_pfirstarc;arc;arc = arc->m_pnextarc){
if(arc->m_padjver == pver)count++;
}
}
return count;
}
int Graphic::CalculateOutDu(VerNode* pver)
{
//對于有向圖計算它的出度
int count = 0;
for(ArcNode* parc = pver->m_pfirstarc;parc;parc = parc->m_pnextarc)
count++;
return count;
}
int Graphic::XL(int x1,int y1,int x2,int y2)
{
int a,b;
a = ((x2-x1)*(x2-x1)*(7*x2/8+x1/8))+((y2-y1)*(y2-y1)*x2)-(y2-y1)*(y2-y1)*(x2-x1)/8-12*(y2-y1)*(x2-x1);
b = (y2-y1)*(y2-y1)+(x2-x1)*(x2-x1);
return a/b;
}
int Graphic::YL(int x1,int y1,int x2,int y2)
{
int a,b,c,d;
a = (y2-y1)*(y2-y1);
b = (x2-x1)*(x2-x1);
c = a*(7*y2/8+y1/8)+b*(y2+12)-b*(y2-y1)/8;
d = a+b;
return c/d;
}
int Graphic::XR(int x1,int y1,int x2,int y2)
{
int a,b;
a = ((x2-x1)*(x2-x1)*(7*x2/8+x1/8))+((y2-y1)*(y2-y1)*x2)-(y2-y1)*(y2-y1)*(x2-x1)/8+12*(y2-y1)*(x2-x1);
b = (y2-y1)*(y2-y1)+(x2-x1)*(x2-x1);
return a/b;
}
int Graphic::YR(int x1,int y1,int x2,int y2)
{
int a,b,c,d;
a = (y2-y1)*(y2-y1);
b = (x2-x1)*(x2-x1);
c = a*(7*y2/8+y1/8)+b*(y2-12)-b*(y2-y1)/8;
d = a+b;
return c/d;
}
BOOL Graphic::TestKeda(VerNode* start,VerNode* end)
{
//判斷start結點到end結點之間是否可達
for(VerNode* pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver){
pnode->m_bvisit = FALSE;
}
int mark = 0;
TKD(start,end,mark);
return mark;
}
void Graphic::TKD(VerNode* start,VerNode* end,int& mark)
{
//判斷keda的具體函數
start->m_bvisit = TRUE;
for(ArcNode* parc = start->m_pfirstarc;parc;parc = parc->m_pnextarc){
VerNode* padj = parc->m_padjver;
if(!padj->m_bvisit){
if(padj == end)mark = 1;
else TKD(padj,end,mark);
}
}
}
int Graphic::PointerToNum(VerNode* pnode)
{
//由結點pnode的指針轉換為它的編號
int count = 0;
for(VerNode* pver = m_verqueue->m_phead;pver;pver = pver->m_pnextver){
if(pver == pnode)return count;
else count++;
}
return -1;
}
void Graphic::ShortestPath(VerNode* pstart,BOOL** p)
{
//求出由結點PSTART到其余各個結點之間的最小路徑
int v0,v,min,adj,w;
VerNode* pmin;
v0 = PointerToNum(pstart);
///////////////////////////////////////////////////////////////////////////////////
for(VerNode* pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver){
pnode->m_bvisit = FALSE;
pnode->m_nvisit = INFINITY;
}
for(ArcNode* parc = pstart->m_pfirstarc;parc;parc = parc->m_pnextarc){
parc->m_padjver->m_nvisit = parc->info;
}
for(pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver){
v = PointerToNum(pnode);
for(w = 0;w<m_verqueue->m_nnum;w++)p[v][w] = FALSE;
if(pnode->m_nvisit<INFINITY){
p[v][v0] = TRUE;
p[v][v] = TRUE;
}
}
////////////////////////////////////////////////////////////////////////////////////
pstart->m_bvisit = TRUE;
pstart->m_nvisit = 0;
/////////////////////////////////////////////////////////////////////////////////////
for(int i = 1;i<m_verqueue->m_nnum;i++){
min = INFINITY;
for(pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver){
if(!pnode->m_bvisit)
if(pnode->m_nvisit<min){
pmin = pnode;
min = pnode->m_nvisit;
}
}
v = PointerToNum(pmin);
pmin->m_bvisit = TRUE;
for(pnode = m_verqueue->m_phead;pnode;pnode = pnode->m_pnextver){
w = PointerToNum(pnode);
adj = INFINITY;
for(parc = pmin->m_pfirstarc;parc;parc = parc->m_pnextarc){
if(pnode == parc->m_padjver)adj = parc->info;
}
if(!pnode->m_bvisit&&(min+adj<pnode->m_nvisit)){
pnode->m_nvisit = min+adj;
for(int j = 0;j<m_verqueue->m_nnum;j++)
p[w][j] = p[v][j];
p[w][w] = TRUE;
}
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -