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


    数据结构图的经常使用算法总结
    本人在校期间写了一个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[n];
    	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


  • 相关阅读:
    java接入钉钉机器人(带源码)
    使用java做一个能赚钱的微信群聊机器人(2020年基于PC端协议最新可用版)
    侠说java8--Stream流操作学习笔记,都在这里了
    Elasticsearch调优篇-慢查询分析笔记
    网络探测和抓包工具 wireshark
    window10远程ubuntu18.04
    springdataJPA mysql myisam innodb
    命令集
    java tmpdir 启动 kafka 命令行
    java jar 启动命令
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6815634.html
Copyright © 2020-2023  润新知