您的位置:首页 > 理论基础 > 数据结构算法

数据结构图的经常使用算法总结

2017-05-06 08:10 393 查看
数据结构图的经常使用算法总结
本人在校期间写了一个win32应用程序,用于回想算法导论图的经常使用算法(图中边的权值为两个圆心的像素点的距离)
1.dijkstra算法求两点之间最短路径:
贪心算法用优先队列实现,每次选择距离起点路径和最短的顶点弹出队列,此顶点最短路径就已经确定

初始图例如以下



选择起点如W



选择终点例如以下:



显示路线:
1)



2)



3)



4)



打开数据,第一行为W距离S点距离。剩下为边的距离一遍參考
470
A <-> D 120
D <-> C 71
C <-> E 93
E <-> G 107
G <-> B 129
B <-> A 83
F <-> C 125
C <-> A 122
C <-> G 118
X <-> O 85
O <-> Y 80
Y <-> D 113
D <-> P 101
P <-> H 112
H <-> Q 80
Q <-> R 86
R <-> I 67
I <-> E 75
E <-> H 74
H <-> I 108
I <-> Q 133
Q <-> Z 68
Z <-> P 83
P <-> C 161
C <-> H 86
E <-> J 101
J <-> S 87
S <-> R 119
I <-> S 68
I <-> J 105
G <-> J 112
J <-> T 70
T <-> K 84
K <-> G 63
G <-> T 83
F <-> K 96
G <-> U 141
U <-> F 82
F <-> B 59
B <-> L 87
L <-> U 53
L <-> V 74
V <-> B 114
B <-> M 101
M <-> W 79
W <-> N 68
N <-> A 76
A <-> M 96
M <-> N 91
M <-> V 61
N <-> X 83
X <-> A 115
A <-> O 99
O <-> D 85
Y <-> P 90
P <-> Q 86
U <-> K 103
B <-> D 147
A <-> L 157
X <-> C 211
O <-> P 137
D <-> H 89
B <-> C 104
C <-> J 181
W <-> A 130
W <-> X 143
N <-> O 128
O <-> B 169
M <-> L 113
L <-> F 65
F <-> G 89
F <-> E 172
H <-> G 167
Q <-> E 142
H <-> R 108
S <-> E 125
E <-> T 140
Q <-> D 137
D <-> E 141
E <-> B 180
O <-> C 142
Y <-> H 177
N <-> B 145
V <-> D 252


2.并查集思想求连通分量
对于原始图1:



结果为



对于实验室图2:



求出结果为:



3.贪心算法PRIM求MST











求MST用 KRUSKAL 算法例如以下:











主要CPP文件
// windowsDesign.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "windowsDesign.h"
#include "class.h"
#include "function.h"
#include "globalVariable.h"
#include "dis_algo_graph.h"
#include "SS_algo_graph.h"
#include <string>
#include "MST_PRIM.h"
#include "MST_KRUSKAL.h"

#define MAX_LOADSTRING 100

// 全局变量:
HINSTANCE hInst;								// 当前实例
TCHAR szTitle[MAX_LOADSTRING];					// 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];			// 主窗体类名

// 全局变量 我自己的
static int nowState = CommondState::emptyState ;
static WindowSize winsize ;
static DataSet graphData;

// 此代码模块中包括的函数的前向声明:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR    lpCmdLine,
int       nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;

// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WINDOWSDESIGN, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// 运行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSDESIGN));

// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}

return (int) msg.wParam;
}

//  函数: MyRegisterClass()
//  目的: 注冊窗体类。
//  凝视:
//    仅当希望
//    此代码与加入到 Windows 95 中的“RegisterClassEx”
//    函数之前的 Win32 系统兼容时,才须要此函数及其使用方法。调用此函数十分重要。
//    这样应用程序就能够获得关联的
//    “格式正确的”小图标。

ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style			= CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc	= WndProc;
wcex.cbClsExtra		= 0;
wcex.cbWndExtra		= 0;
wcex.hInstance		= hInstance;
wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSDESIGN));
wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_WINDOWSDESIGN);
wcex.lpszClassName	= szWindowClass;
wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

return RegisterClassEx(&wcex);
}

//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗体
//
//   凝视:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗体。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;

hInst = hInstance; // 将实例句柄存储在全局变量中

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if (!hWnd)
{
return FALSE;
}

long style = GetWindowLong(hWnd,GWL_STYLE);//获得窗体风格

winsize.screenX = GetSystemMetrics(SM_CXSCREEN);//获取整个屏幕右下角X坐标
winsize.screenY = GetSystemMetrics(SM_CYSCREEN)-40;//屏幕Y坐标

SetWindowPos(hWnd, NULL,0,0,winsize.screenX,winsize.screenY,SWP_NOZORDER);//改变窗体位置、尺寸和Z序

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

return TRUE;
}

//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的: 处理主窗体的消息。
//
//  WM_COMMAND	- 处理应用程序菜单
//  WM_PAINT	- 绘制主窗体
//  WM_DESTROY	- 发送退出消息并返回

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static Point * myPoint = new Point();
static TCHAR greet[] = TEXT("A");
static Line * myline = new Line();
static Point start,end;
static list<Line> result;
static list<Line> result_kruskal;

int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_COMMAND:
wmId    = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch ( wmId )
{
case IDM_GRAPH_CLEAR:
{
clearWindow( hWnd,winsize );
graphData.lineList.clear();
graphData.pointList.clear();
}
break;
case IDM_MST_PRIM:
{
//1.得到全部边
//2.显示全部边
if(! result_kruskal.empty())
{
for( list<Line>::iterator it = result_kruskal.begin(); it != result_kruskal.end(); it++ )
{
it -> penColor = green ;
drawLine( hWnd,*it ) ;
}
result_kruskal.clear();
}
result_kruskal = mstPrim( graphData, graphData.pointList.front() );
if( ! result_kruskal.empty() )
{
for( list<Line>::iterator it = result_kruskal.begin(); it != result_kruskal.end(); it++ )
{
it -> penColor = red ;
drawLine( hWnd,*it ) ;
Sleep(1000);
}
}

}
break;

case IDM_MST_KEUSKAL:
{
////1.得到全部边
////2.显示全部边
if(! result_kruskal.empty())
{
for( list<Line>::iterator it = result_kruskal.begin(); it != result_kruskal.end(); it++ )
{
it -> penColor = green ;
drawLine( hWnd,*it ) ;
}
result_kruskal.clear();
}
result_kruskal = mstKruskal( graphData );
if( ! result_kruskal.empty() )
{
for( list<Line>::iterator it = result_kruskal.begin(); it != result_kruskal.end(); it++ )
{
it -> penColor = red ;
drawLine( hWnd,*it ) ;
Sleep(1000);
}
}
}
break;

case IDM_SET_SEARCH:
{
int* ssdata = setSsearchAlgorithm( graphData );
int i=0;
for( list<Point>::iterator it=graphData.pointList.begin(); it != graphData.pointList.end(); it++)
{
(*it).brushColor = RGB(255-ssdata[i]*70,ssdata[i]*70,100+ssdata[i]*70);
i++;
drawPoint(hWnd,*it);
}
}
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case IDM_FILE_SAVE:
{
saveGraph( graphData ) ;
}
break;
case IDM_FILE_OPEN:
{
graphData.pointList.clear( );
graphData.lineList.clear( );
result_kruskal.clear( );
clearWindow( hWnd,winsize );
openGraph( graphData );
drawGraph( hWnd,graphData );
}
break;
case IDM_INSERT_NODE:
nowState = CommondState::insertNodeState ;
break ;
case IDM_INSERT_OVER:
nowState = CommondState::emptyState ;
break ;
case IDM_INSERT_LINE:
nowState = CommondState::insertLineState ;
break;
case IDM_SEARCH_START :
nowState = CommondState::selectStartState ;
break;
case IDM_SEARCH_END :
nowState = CommondState::selectEndState ;
break ;
case IDM_SEARCH_OVER :
nowState = CommondState::emptyState ;
{
if( ! result.empty() )
{
for( list<Line>::iterator it = result.begin(); it != result.end(); it++ )
{
it->penColor = green ;
drawLine( hWnd,*it ) ;
}
}

if( start.legal(winsize) && end.legal(winsize) )
{
result = singleDistance( graphData.pointList,graphData.lineList,start,end );
if( ! result.empty() )
for( list<Line>::iterator it = result.begin();it != result.end(); it++ )
{
Sleep(1000);
it->penColor = red;
drawLine( hWnd,*it );
}

}

}
break;
case IDM_DATA_OPEN:
{
if( AllocConsole() )
{
freopen("CONOUT$","w",stdout);
cout<<graph_data[start.key-'A'][end.key-'A']<<endl;
for(list<Line>::iterator  it=graphData.lineList.begin(); it != graphData.lineList.end(); it++)
{
cout<<(*it).start.key<<" <-> "<<(*it).end.key<<" "<<(*it).weight<<endl;
}
}
else
{
FreeConsole();
AllocConsole() ;

freopen("CONOUT$","w",stdout);
cout<<graph_data[start.key-'A'][end.key-'A']<<endl;
for(list<Line>::iterator  it=graphData.lineList.begin(); it != graphData.lineList.end(); it++)
{
cout<<(*it).start.key<<" <-> "<<(*it).end.key<<" "<<(*it).weight<<endl;
}

}
}
break;
case IDM_DATA_CLOSE:
{
FreeConsole();
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam) ;
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);

// TODO: 在此加入随意画图代码...
{
//1.画出边界
//2.画出全部节点
//3.画出全部边
//Line bianjie ;
//bianjie.start.x = winsize.screenX / 4 * 3;
//bianjie.start.y = 0;

//bianjie.end.x = winsize.screenX / 4 * 3 ;
//bianjie.end.y = winsize.screenY ;
//drawLine( hWnd,bianjie );

//drawGraph(hWnd,graphData);
}

EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;

case WM_LBUTTONDOWN:
switch( nowState  )
{
// 插入节点
case CommondState::insertNodeState:
{
// 获取位置
myPoint->x = LOWORD(lParam);
myPoint->y = HIWORD(lParam);
if( myPoint->legal(winsize) )
{
drawPoint(hWnd,*myPoint);

// 制作keyword
if(! graphData.pointList.empty())
greet[0] = TCHAR(graphData.pointList.back().key+1);
myPoint->key = (char)greet[0];
TextOut( GetDC(hWnd),myPoint->x - 5,myPoint->y - myPoint->r * 3,greet,1 ) ;

//greet[0] ++;

// 保存节点
graphData.pointList.push_back(*myPoint);
}

}
break;

case CommondState::insertLineState:
{
if(myline->down == false)
{
// 获取位置
Point point ;
point.x = LOWORD(lParam) ;
point.y = HIWORD(lParam) ;

// 检查模糊节点
bool  result = checkPointInList(point,graphData.pointList) ;

if( result )
{
// 标记按下
myline -> down = true ;
myline -> start = point;
myline -> end = point;
}
}
}
break ;

case CommondState::selectStartState:
{
//1.获取坐标
//2.检查坐标
//3.假设是节点:保存起点
//4.否则继续寻找

Point point ;
point.x = LOWORD(lParam) ;
point.y = HIWORD(lParam) ;

bool result = checkPointInList( point,graphData.pointList );
if( result )
{
if( start.legal(winsize) )
{
start.brushColor = green;
drawPoint(hWnd,start);
}

start = point;
start.brushColor = red;
drawPoint(hWnd,start);
}
}
break;

case CommondState::selectEndState:
{
//1.获取坐标
//2.检查坐标
//3.假设是节点:保存起点
//4.否则继续寻找

Point point ;
point.x = LOWORD( lParam ) ;
point.y = HIWORD( lParam ) ;

bool result = checkPointInList( point,graphData.pointList );
if( result && checkTwoPoint( point,start ) == false )
{
if( end.legal( winsize ) )
{
end.brushColor = green ;
drawPoint( hWnd,end ) ;
}

end = point;
end.brushColor = blue ;
drawPoint(hWnd,end) ;
}
}
break;
}

break;

case WM_MOUSEMOVE:
{
if( nowState == CommondState::insertLineState && myline->down == true )
{
drawLine(hWnd,*myline);
Point point ;
point.x = LOWORD(lParam) ;
point.y = HIWORD(lParam) ;
myline->end = point;
drawLine( hWnd,*myline);
}
}

break;

case WM_LBUTTONUP:
{
if( nowState == CommondState::insertLineState && myline->down == true)
{
// 擦除上一条
drawLine( hWnd,*myline) ;
Point point ;
point.x = LOWORD(lParam) ;
point.y = HIWORD(lParam) ;

// 检測节点
bool result = checkPointInList(point,graphData.pointList);
if( result && checkTwoPoint(point,myline->start) == false )
{
myline->end = point ;
myline->down = false ;
myline->realLine = true ;
myline->weight = disTwoPoint(myline->start,myline->end);
drawLine( hWnd,*myline ) ;
graphData.lineList.push_back( *myline ) ;
myline ->realLine = false ;

}

// 错误抬起
else if(result == false)
{
drawLine( hWnd,*myline);
}
}
}
break;

default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}


class.h
#ifndef class_h
#define class_h

#include <list>
#include <iostream>
using namespace std;

#define green RGB(50,205,50)
#define red RGB(255,0,0)
#define blue RGB(0,0,255)
#define white RGB(255,255,255)

#define al_red 1
#define al_white 2
#define al_black 3

class WindowSize
{
public:
int screenX ;
int screenY ;
WindowSize()
{
screenX = screenY = 0;
}

};

class Point
{
public:
int x;
int y;
int r;
char key;
COLORREF brushColor;

Point( )
{
x = 0;
y = 0;
r = 10;
key = '*';
brushColor =  green;
}

Point(const int & x,const int & y,const char &key )
{
this->x = x;
this->y = y;
r = 10;
this->key = key ;
brushColor =   green;

}

Point(const int &x,const int & y)
{
this->x = x;
this->y = y;
r = 10;
this->key = '*' ;
brushColor =   green;

}

Point(const Point & point)
{
this->x = point.x;
this->y = point.y;
r = 10;
this->key = point.key;
brushColor = point.brushColor;
}

bool legal(const WindowSize  &mywin)
{
bool result = true ;
if(x <= 0 || x >= mywin.screenX || y <= 0 || y >= mywin.screenY)
{
result = false;
}
return result;
}

};

class Line
{
public:
Point start;
Point end;
int weight;
bool down ;
bool realLine;
int penWidth;
COLORREF penColor;
Line()
{
realLine = false;
penWidth = 2;
penColor = green;
down = false;
weight = -1;
}

};

class DataSet
{
public:
list<Point>  pointList ;
list<Line>  lineList ;
};

#endif


dijkstra算法

dis_algo_graph.h

#ifndef ALGO_H
#define ALGO_H

#include <iostream>
#include <list>
#include "class.h"
#include <utility>
#include <queue>
#include "function.h"
#include <string>
#include <map>
using namespace std;

static int ** graph_data ;
static char startkey;

class Node
{
public:

char key;

Node( char key )
{
this -> key = key;
}

Node()
{
key = '*';
}

};

bool operator< (const Node & a,const Node & b)
{
return graph_data[startkey-'A'][a.key-'A'] > graph_data[startkey-'A'][b.key-'A'];
}
list<Line> findByMap( list<char> & road, list<Line>& linelist );

list<Line> singleDistance( list<Point> & pointlist,list<Line> & linelist,const Point & start,const Point & end)
{
//disktra algorithm
//1.利用邻接矩阵存储数据
//2.利用优先队列:
//	1)放入起点
//	2)以此寻找终点

int* color = new int[pointlist.size()];
int* parent = new int[pointlist.size()];

for(int i=0; i<pointlist.size(); i++)
{
color[i] = al_white;
parent[i] = -1;
}

graph_data = new int*[ pointlist.size() ];
for( int i=0; i<pointlist.size(); i++ )
graph_data[i] = new int[ pointlist.size() ];

for( int i=0; i<pointlist.size(); i++)
for( int j=0; j<pointlist.size(); j++)
{
graph_data[i][j] = -1;
if( i == j )
graph_data[i][j] = 0;
}

for(list<Line>::iterator it = linelist.begin(); it != linelist.end(); it ++)
{
graph_data[(*it).start.key-'A'][(*it).end.key-'A'] = disTwoPoint((*it).start,(*it).end);
graph_data[(*it).end.key-'A'][(*it).start.key-'A'] = disTwoPoint((*it).start,(*it).end);
}

priority_queue<Node,vector<Node>,less<vector<Node>::value_type>> Q;
list<char> result ;

Node first(start.key);
color[start.key-'A'] = al_red;
Q.push( first );
Node now ;
startkey = start.key;
while(! Q.empty() )
{
now = Q.top();
color[now.key-'A'] = al_black;
Q.pop();

if( now.key == end.key )
break;
for(int i=0; i<pointlist.size(); i++)
{
if(  now.key - 'A' != i && graph_data[now.key-'A'][i] != -1 )
{
if( color[i] == al_white )
{
parent[i] = now.key - 'A';

graph_data[start.key-'A'][i] = graph_data[now.key-'A'][i] + graph_data[start.key-'A'][now.key-'A'] ;
first.key = 'A' + i ;
color[i] = al_red;
Q.push( first ) ;
}

else if( color[i] = al_red )
{

if( graph_data[start.key-'A'][i] > graph_data[now.key-'A'][i] + graph_data[start.key-'A'][now.key-'A'] )
{
list<Node> zhongjian;
while(! Q.empty() )
{
zhongjian.push_back(Q.top());
Q.pop();
}
parent[i] = now.key - 'A';
graph_data[start.key-'A'][i] = graph_data[now.key-'A'][i] + graph_data[start.key-'A'][now.key-'A'] ;
while( ! zhongjian.empty() )
{
Q.push( zhongjian.front() );
zhongjian.pop_front();
}
}

}
}
}
}

char road = end.key;
while( road != start.key )
{
if( parent[road-'A'] == -1)
break;
result.push_front( road );
road = 'A'+ parent[road-'A'];
}
if(! result.empty())
result.push_front(road);

return findByMap(result,linelist);

}

list<Line> findByMap( list<char> & road,list<Line>& linelist )
{
//1.有用map保存数据
//2.搜素数据
//3.返回结果

string strnull;
map<string,Line> mymap;
for(list<Line>::iterator it=linelist.begin();it != linelist.end(); it++)
{
mymap.insert( make_pair(strnull +(*it).start.key + (*it).end.key,*it) );
mymap.insert( make_pair(strnull +(*it).end.key + (*it).start.key,*it) );
}

list<Line> result;

if(road.size() > 1)
while(  road.size()>1 )
{

strnull = road.front();
road.pop_front();
strnull += road.front();

result.push_back( mymap.find( strnull )->second );
}
return result;
}

#endif


function.h
#ifndef function_h
#define function_h

#include<iostream>
#include<math.h>
#include<fstream>
#include<list>
#include "class.h"
#include<map>
using namespace std;

void drawLine(HWND hwnd,Line  myline)
{
HPEN pen,oldpen;
pen = CreatePen(PS_SOLID,myline.penWidth,myline.penColor);
HDC hdc = GetDC(hwnd);
oldpen = (HPEN)SelectObject(hdc,pen);
if(myline.realLine == false)
SetROP2(hdc,R2_NOTXORPEN);
else
SetROP2(hdc,R2_COPYPEN);
MoveToEx(hdc,myline.start.x,myline.start.y,NULL);
LineTo(hdc,myline.end.x,myline.end.y);

SelectObject(hdc,oldpen);
DeleteObject(pen);
ReleaseDC(hwnd,hdc);
}

void drawPoint(HWND hwnd,const Point & mypoint)
{

HBRUSH brush ;
HPEN hpen,oldpen;
hpen = CreatePen(PS_SOLID,4,mypoint.brushColor);
brush = CreateSolidBrush(mypoint.brushColor);
HDC hdc = GetDC(hwnd);
oldpen = (HPEN) SelectObject( hdc,hpen);
SelectObject( hdc,brush );
SetROP2( hdc,R2_COPYPEN );

Ellipse( hdc,mypoint.x - mypoint.r , mypoint.y - mypoint.r , mypoint.x + mypoint.r , mypoint.y + mypoint.r );

SelectObject(hdc,oldpen);
DeleteObject(hpen);
ReleaseDC(hwnd,hdc);
}

bool checkTwoPoint(const Point & a,const Point & b)
{
bool result = false;
int abx = abs(a.x - b.x);
int aby = abs(a.y - b.y);

if(abx*abx + aby*aby < a.r*a.r )
result = true ;
return result;
}

bool checkPointInList( Point &a, list<Point> mylist )
{
bool result = false ;
list<Point>::iterator it ;
if(! mylist.empty())
for( it = mylist.begin(); it != mylist.end(); it ++ )
{
if( checkTwoPoint(a,*it) == true )
{
result = true ;
a = (*it) ;
break ;
}
}
return result;
}

int disTwoPoint(const Point & start,const Point & end)
{
int x_w = abs(end.x - start.x);
int y_w = abs(start.y - end.y);
return (int)sqrt(float(x_w*x_w + y_w*y_w));
}

void drawGraph(HWND hWnd, DataSet & graphData)
{
TCHAR greet[1] ;
if(! graphData.pointList.empty())
{
for(list<Point>::iterator it = graphData.pointList.begin(); it != graphData.pointList.end(); it++)
{
greet[0] = (*it).key ;
TextOut( GetDC(hWnd),(*it).x - 5,(*it).y - (*it).r*3,greet,1 ) ;
drawPoint(hWnd,*it) ;
}
}

if(! graphData.lineList.empty())
{
for(list<Line>::iterator it = graphData.lineList.begin(); it!=graphData.lineList.end(); it++)
{
drawLine(hWnd,*it);
}
}
}

void saveGraph( DataSet & graphData )
{
//1.保存全部节点
//2.保存全部边

ofstream writer;
writer.open("graph.txt");
writer<<graphData.pointList.size()<<endl;
for(list<Point>::iterator it = graphData.pointList.begin();it != graphData.pointList.end();it++)
writer<<(*it).key<<" "<<(*it).x<<" "<<(*it).y<<endl;
writer<<graphData.lineList.size()<<endl;
for(list<Line>::iterator it = graphData.lineList.begin(); it != graphData.lineList.end(); it++)
writer<<(*it).start.key<<" "<<(*it).end.key<<endl;
writer.close();
}

void openGraph( DataSet & graphData )
{
//1.读取全部节点
//2.读取全部边

ifstream reader;
reader.open("graph.txt");
map<char,Point> mymap;
int i;
Point point ;
Line line ;
for( reader>>i;i>0;i-- )
{
reader>>point.key;
reader>>point.x;
reader>>point.y;
graphData.pointList.push_back( point );
mymap.insert( make_pair( point.key,point ) );
}

for( reader>>i; i>0; i-- )
{
reader>>line.start.key ;
line.start = ( mymap.find(line.start.key) )-> second ;
reader>>line.end.key ;
line.end = ( mymap.find(line.end.key) )-> second ;

line.realLine = true ;
line.weight = disTwoPoint( line.start,line.end ) ;
graphData.lineList.push_back( line );

}

reader.close();
}

void clearWindow( HWND hwnd,const WindowSize & winsize )
{
HBRUSH brush;
brush = CreateSolidBrush( white );
SelectObject( GetDC(hwnd),brush );
Rectangle( GetDC(hwnd),0,0,winsize.screenX,winsize.screenY );
DeleteObject( brush );
}

#endif


globalVariable.h

#ifndef globalVariable_h
#define globalVariable_h

#include <list>
#include "class.h"

class CommondState
{
public:
static const int emptyState = 0;
static const int insertNodeState = 1;
static const int insertLineState = 2;
static const int selectStartState = 3;
static const int selectEndState = 4;

};

#endif


MST_KRUSKAL.h

#ifndef mst_kruskal
#define mst_kruskal

#include "class.h"
#include "function.h"
#include <iostream>
#include <list>
using namespace std;

int * mark;

bool linecom (const Line & a,const Line & b)
{
return a.weight < b.weight;
}

void kruskal_union(const int & a,const int & b,const int & n);

list<Line> mstKruskal( DataSet dataset )
{
/*
1.对全部边排序
2.依次找出最小的边,在保证不成环的情况下并连接
3.返回边集合
*/

// 1
const int n = dataset.pointList.size();
mark = new int
;
for(int i=0;i<n;i++)
{
mark[i] = i;
}
dataset.lineList.sort( linecom );

// 2
list<Line> result;
Line edge;
while( ! dataset.lineList.empty() )
{
edge = dataset.lineList.front();
dataset.lineList.pop_front();
if( mark[ edge.start.key - 'A' ] != mark[ edge.end.key - 'A' ] )
{
result.push_back(edge);
kruskal_union(mark[ edge.start.key - 'A' ],mark[ edge.end.key - 'A' ],n);
}
}

// 3
return result;
}

void kruskal_union( const int & a,const int & b,const int & n )
{
int min_num = min(a,b);
int max_num = max(a,b);
for(int i=0;i<n;i++)
{
if( mark[i] == max_num )
mark[i] = min_num;
}
}

#endif


MST_PRIM.h

#ifndef MST_PRIM
#define MST_PRIM

#include <iostream>
#include <list>
#include "class.h"
#include <utility>
#include <queue>
#include "function.h"
#include <string>
#include <map>
using namespace std;

static int * mst_prior_queue_key;
static int ** mst_graph_data;
static int n;

class PriorNode
{
public:
int data;
PriorNode()
{
data = MAXINT;
}

};

bool operator < ( const PriorNode & a , const PriorNode & b )
{
return mst_prior_queue_key[a.data] > mst_prior_queue_key[b.data] ;
}

list<Line> findByMapWithMST( list<pair<char,char>> & road,list<Line>& linelist );

list<Line> mstPrim(DataSet & dataset ,const Point & start)
{
//1.初始化优先队列和key值
//2.以此取出最小的邻边,并不断更新key值
//3.返回结果边集合

// 1
priority_queue<PriorNode,vector<PriorNode>,less<vector<PriorNode>::value_type>> Q;
PriorNode node,innode;
int num_node = dataset.pointList.size();
n = num_node;
int *al_color = new int[dataset.pointList.size()];

mst_graph_data = new int*[num_node];
for( int i=0; i<num_node; i++ )
{
mst_graph_data[i] = new int[num_node];
for( int j=0;j<num_node;j++ )
{
mst_graph_data[i][j] = MAXINT;
if( i == j )
mst_graph_data[i][j] = 0;
}
}
for(list<Line>::iterator it = dataset.lineList.begin(); it != dataset.lineList.end();  it ++)
{
mst_graph_data[(*it).start.key-'A'][(*it).end.key-'A'] = (*it).weight;
mst_graph_data[(*it).end.key-'A'][(*it).start.key-'A'] = (*it).weight;
}
mst_prior_queue_key = new int[num_node];
for(int i=0;i<num_node;i++)
mst_prior_queue_key[i] = MAXINT;
mst_prior_queue_key[start.key - 'A'] = 0;

// 2
list<pair<char,char>> result;
int * parent = new int[num_node];
for(int i=0;i<num_node;i++)
{
parent[i] = MAXINT;
al_color[i] = al_white;
}
node.data = start.key-'A';
al_color[node.data] = al_red;
Q.push( node );
while( ! Q.empty() )
{
node = Q.top();
al_color[node.data] = al_black ;
if( node.data != start.key - 'A' )
result.push_back( make_pair( parent[node.data]+'A' , node.data+'A' ) );
Q.pop();

for( int i=0; i < num_node; i++ )
{
if( al_color[i] == al_red )
{
if( mst_graph_data[node.data][i] < mst_prior_queue_key[i] )
{
list<PriorNode> zhongjian ;
while(! Q.empty() )
{
zhongjian.push_back(Q.top());
Q.pop();
}
mst_prior_queue_key[ i ] = mst_graph_data[node.data][i] ;
parent[i] = node.data ;
while( ! zhongjian.empty() )
{
Q.push( zhongjian.front() );
zhongjian.pop_front();
}
}
}
else if( al_color[i] == al_white )
{
if( mst_graph_data[node.data][i] < mst_prior_queue_key[i] )
{
mst_prior_queue_key[ i ] = mst_graph_data[node.data][i] ;
parent[i] = node.data ;
al_color[i] = al_red;
innode.data =  i;
Q.push( innode );
}
}
}
}

return findByMapWithMST(result,dataset.lineList);
}

list<Line> findByMapWithMST( list<pair<char,char>> & road,list<Line>& linelist )
{
//1.有用map保存数据
//2.搜素数据
//3.返回结果

string strnull;
map<string,Line> mymap;
for(list<Line>::iterator it=linelist.begin();it != linelist.end(); it++)
{
mymap.insert( make_pair(strnull +(*it).start.key + (*it).end.key,*it) );
mymap.insert( make_pair(strnull +(*it).end.key + (*it).start.key,*it) );
}

list<Line> result;

while(  road.size()>0 )
{

strnull = road.front().first;
strnull += road.front().second;
road.pop_front();

result.push_back( mymap.find( strnull )->second );
}
return result;
}

#endif


并查集算法

SS_algo_graph.h

#ifndef SS_H
#define SS_E

#include <iostream>
#include <list>
#include "class.h"
using namespace std;

//0.并查集
//1.给每一个节点设置标志颜色位
//2.检查每一条边,能否够合并
//3.合并边中的两个点所在的集合
//4.返回图的颜色集合

void set_union(const int & a,const int & b,const int & n);

int * pointset;
int * setSsearchAlgorithm( DataSet & graph )
{
const int n = graph.pointList.size();
const int m = graph.lineList.size();
pointset = new int[ n ];
bool ** edgeset = new bool*[ m ];
for ( int i=0;i<n;i++ )
pointset[i] = i;
for( int i=0;i<m;i++ )
{
edgeset[i] = new bool[m];
for (int j =0;j<m;j++)
{
edgeset[i][j] = true;
}
}

for(list<Line>::iterator it = graph.lineList.begin();it != graph.lineList.end();it++)
{
if(edgeset[(*it).start.key-'A'][(*it).end.key-'A'] == true)
{
if(pointset[(*it).start.key-'A'] != pointset[(*it).end.key-'A'])
{
set_union(pointset[(*it).start.key-'A'] , pointset[(*it).end.key-'A'],n);
}
edgeset[(*it).start.key-'A'][(*it).end.key-'A'] = false;
}
}

return pointset;
}

void set_union(const int & a,const int & b,const int & n)
{
int min_num = min(a,b);
int max_num = max(a,b);
for(int i=0;i<n;i++)
{
if( pointset[i] == max_num )
pointset[i] = min_num;
}
}

#endif


源程序打包下载地址: http://pan.baidu.com/s/1kTxFiZl
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: