数据结构图的经常使用算法总结
本人在校期间写了一个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
#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 result; static list 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::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::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::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::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::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::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::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<::iterator it=graphData.lineList.begin(); it != graphData.lineList.end(); it++) { cout<<(*it).start.key<<" <-> "<<(*it).end.key<<" "<<(*it).weight<::iterator it=graphData.lineList.begin(); it != graphData.lineList.end(); it++) { cout<<(*it).start.key<<" <-> "<<(*it).end.key<<" "<<(*it).weight<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
#include
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 pointList ;
list lineList ;
};
#endif
dijkstra算法
dis_algo_graph.h
#ifndef ALGO_H
#define ALGO_H
#include
#include
#include "class.h"
#include
#include
#include "function.h"
#include
#include
function.h
#ifndef function_h
#define function_h
#include
#include
#include
#include
#include "class.h"
#include
globalVariable.h
#ifndef globalVariable_h
#define globalVariable_h
#include
#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
#include
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 mstKruskal( DataSet dataset )
{
/*
1.对全部边排序
2.依次找出最小的边,在保证不成环的情况下并连接
3.返回边集合
*/
// 1
const int n = dataset.pointList.size();
mark = new int[n];
for(int i=0;i 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
MST_PRIM.h
#ifndef MST_PRIM
#define MST_PRIM
#include
#include
#include "class.h"
#include
#include
#include "function.h"
#include
#include
并查集算法
SS_algo_graph.h
#ifndef SS_H
#define SS_E
#include
#include
#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::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
源程序打包下载地址: http://pan.baidu.com/s/1kTxFiZl