zoukankan      html  css  js  c++  java
  • 数据结构实验3(图的DFS和BFS实现)

    实现邻接矩阵和邻接表两种不同存储结构上实现图的基本运算, 在MGraph类中扩充添加DFS()和BFS()函数.

    包括的运算: 插入一条边, 删除一条边, 查询边是否存在, 图的深度优先搜索和广度优先搜索.

    广度优先搜索利用队列作为辅助的数据结构, 元素类型是树的结点. 

    实现代码:

    #include "iostream"
    #include "cstdio"
    #include "cstring"
    #include "algorithm"
    #include "queue"
    #include "stack"
    #include "cmath"
    #include "utility"
    #include "map"
    #include "set"
    #include "vector"
    #include "list"
    #include "string"
    using namespace std;
    typedef long long ll;
    const int MOD = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    enum ResultCode { Underflow, Duplicate, Failure, Success, NotPresent };
    
    template <class T>
    class SeqQueue
    {
    public:
    	SeqQueue(int mSize);
    	~SeqQueue() { delete []q; }
    	bool IsEmpty() const { return front == rear; } // front与rear相等时循环队列为空
    	bool IsFull() const { return (rear + 1) % maxSize == front; } // front与(rear + 1) % maxSize相等时循环队列满
    	bool Front(T &x) const;
    	bool EnQueue(T x);
    	bool DeQueue();
    	void Clear() { front = rear = 0; }
    	/* data */
    private:
    	int front, rear, maxSize; // 队头元素 队尾元素 数组最大长度
    	T *q;
    };
    template <class T>
    SeqQueue<T>::SeqQueue(int mSize)
    {
    	maxSize = mSize;
    	q = new T[maxSize];
    	front = rear = 0;
    }
    template <class T>
    bool SeqQueue<T>::Front(T &x) const
    {
    	if(IsEmpty()) { // 空队列处理
    		cout << "SeqQueue is empty" << endl;
    		return false;
    	}
    	x = q[(front + 1) % maxSize];
    	return true;
    }
    template <class T>
    bool SeqQueue<T>::EnQueue(T x)
    {
    	if(IsFull()) { // 溢出处理
    		cout << "SeqQueue is full" << endl;
    		return false;
    	}
    	q[(rear = (rear + 1) % maxSize)] = x;
    	return true;
    }
    template <class T>
    bool SeqQueue<T>::DeQueue()
    {
    	if(IsEmpty()) { // 空队列处理
    		cout << "SeqQueue is empty" << endl;
    		return false;
    	}
    	front = (front + 1) % maxSize;
    	return true;
    }
    template <class T>
    class Graph
    {
    public:
    	virtual	~Graph() {};
    	virtual ResultCode Insert(int u, int v, T &w) = 0;
    	virtual ResultCode Remove(int u, int v) = 0;
    	virtual bool Exist(int u, int v) const = 0;
    	/* data */
    };
    template <class T>
    class MGraph: public Graph<T>
    {
    public:
    	MGraph(int mSize, const T& noedg);
    	~MGraph();
    	ResultCode Insert(int u, int v, T &w);
    	ResultCode Remove(int u, int v);
    	bool Exist(int u, int v) const;
    	int Vertices() const { return n; }
    	void Output();
    	void DFS();
    	void BFS();
    protected:
    	T **a;
    	T noEdge;
    	int n, e;
    	void DFS(int v, bool *vis);
    	void BFS(int v, bool *vis);
    	/* data */
    };
    template <class T>
    void MGraph<T>::Output()
    {
    	for(int i = 0; i < n; ++i) {
    		for(int j = 0; j < n; ++j)
    			if(a[i][j] == noEdge) cout << "NE	";
    			else cout << a[i][j] << "	";
    		cout << endl;
    	}
    	cout << endl << endl << endl;
    }
    template <class T>
    MGraph<T>::MGraph(int mSize, const T &noedg)
    {
    	n = mSize, e = 0, noEdge = noedg;
    	a = new T *[n];
    	for(int i = 0; i < n; ++i) {
    		a[i] = new T[n];
    		for(int j = 0; j < n; ++j)
    			a[i][j] = noEdge;
    		a[i][i] = 0;
    	}
    }
    template <class T>
    MGraph<T>::~MGraph()
    {
    	for(int i = 0; i < n; ++i)
    		delete []a[i];
    	delete []a;
    }
    template <class T>
    bool MGraph<T>::Exist(int u, int v) const
    {
    	if(u < 0 || v < 0 || u > n - 1 || v > n - 1 || u == v || a[u][v] == noEdge) return false;
    	return true;
    }
    template <class T>
    ResultCode MGraph<T>::Insert(int u, int v, T &w)
    {
    	if(u < 0 || v < 0 || u > n - 1 || v > n - 1 || u == v) return Failure;
    	if(a[u][v] != noEdge) return Duplicate;
    	a[u][v] = w;
    	e++;
    	return Success; 
    }
    template <class T>
    ResultCode MGraph<T>::Remove(int u, int v)
    {
    	if(u < 0 || v < 0 || u > n - 1 || v > n - 1 || u == v) return Failure;
    	if(a[u][v] == noEdge) return NotPresent;
    	a[u][v] = noEdge;
    	e--;
    	return Success;
    }
    template <class T>
    void MGraph<T>::DFS()
    {
    	bool *vis = new bool[n];
    	memset(vis, false, n);
    	for(int i = 0; i < n; ++i)
    		if(!vis[i]) DFS(i, vis);
    	delete []vis;
    }
    template <class T>
    void MGraph<T>::DFS(int v, bool *vis)
    {
    	vis[v] = true;
    	cout << ' ' << v;
    	for(int i = 0; i < n; ++i)
    		if(a[v][i] != noEdge && a[v][i] != 0 && !vis[i]) DFS(i, vis);
    }
    template <class T>
    void MGraph<T>::BFS()
    {
    	bool *vis = new bool[n];
    	memset(vis, false, n);
    	for(int i = 0; i < n; ++i)
    		if(!vis[i]) BFS(i, vis);
    	delete []vis;
    }
    template <class T>
    void MGraph<T>::BFS(int v, bool *vis)
    {
    	SeqQueue<int> q(n);
    	vis[v] = true;
    	cout << ' ' << v;
    	q.EnQueue(v);
    	while(!q.IsEmpty()) {
    		q.Front(v);
    		q.DeQueue();
    		for(int i = 0; i < n; ++i)
    			if(a[v][i] != noEdge && a[v][i] != 0 && !vis[i]) {
    				vis[i] = true;
    				cout << ' ' << i;
    				q.EnQueue(i);
    			}
    	}
    }
    template <class T>
    struct ENode
    {
    	ENode() { nxtArc = NULL; }
    	ENode(int vertex, T weight, ENode *nxt) {
    		adjVex = vertex;
    		w = weight;
    		nxtArc = nxt;
    	}
    	int adjVex;
    	T w;
    	ENode *nxtArc;
    	/* data */
    };
    template <class T>
    class LGraph: public Graph<T>
    {
    public:
    	LGraph(int mSize);
    	~LGraph();
    	ResultCode Insert(int u, int v, T &w);
    	ResultCode Remove(int u, int v);
    	bool Exist(int u, int v) const;
    	int Vertices() const { return n; }
    	void Output();
    protected:
    	ENode<T> **a;
    	int n, e;
    	/* data */
    };
    template <class T>
    void LGraph<T>::Output()
    {
    	ENode<T> *q;
    	for(int i = 0; i < n; ++i) {
    		q = a[i];
    		while(q) {
    			cout << '(' << i << ' ' << q -> adjVex << ' ' << q -> w << ')';
    			q = q -> nxtArc;
    		}
    		cout << endl;
    	}
    	cout << endl << endl;
    }
    template <class T>
    LGraph<T>::LGraph(int mSize)
    {
    	n = mSize;
    	e = 0;
    	a = new ENode<T>*[n];
    	for(int i = 0; i < n; ++i)
    		a[i] = NULL;
    }
    template <class T>
    LGraph<T>::~LGraph()
    {
    	ENode<T> *p, *q;
    	for(int i = 0; i < n; ++i) {
    		p = a[i];
    		q = p;
    		while(p) {
    			p = p -> nxtArc;
    			delete q;
    			q = p;
    		}
    	}
    	delete []a;
    }
    template <class T>
    bool LGraph<T>::Exist(int u, int v) const
    {
    	if(u < 0 || v < 0 || u > n - 1 || v > n - 1 || u == v) return false;
    	ENode<T> *p = a[u];
    	while(p && p -> adjVex != v) p = p -> nxtArc;
    	if(!p) return false;
    	return true;
    }
    template <class T>
    ResultCode LGraph<T>::Insert(int u, int v, T &w)
    {
    	if(u < 0 || v < 0 || u > n - 1 || v > n - 1 || u == v) return Failure;
    	if(Exist(u, v)) return Duplicate;
    	ENode<T> *p = new ENode<T>(v, w, a[u]);
    	a[u] = p;
    	e++;
    	return Success;
    }
    template <class T>
    ResultCode LGraph<T>::Remove(int u, int v)
    {
    	if(u < 0 || v < 0 || u > n - 1 || v > n - 1 || u == v) return Failure;
    	ENode<T> *p = a[u], *q = NULL;
    	while(p && p -> adjVex != v) {
    		q = p;
    		p = p -> nxtArc;
    	}
    	if(!p) return NotPresent;
    	if(q) q -> nxtArc = p -> nxtArc;
    	else a[u] = p -> nxtArc;
    	delete p;
    	e--;
    	return Success;
    }
    int main(int argc, char const *argv[])
    {
    	int n, g;
    	cout << "请输入元素的个数: ";
    	cin >> n;
    	MGraph<int> A(n, INF);
    	LGraph<int> B(n);
    	cout << "请输入边的条数: ";
    	cin >> g;
    	int *a = new int[g];
    	int *b = new int[g];
    	int *w = new int[g];
    	for(int i = 0; i < g; ++i)
    	{
    		cout << "请输入边及权值: ";
    		cin>> a[i] >> b[i] >> w[i];
    		A.Insert(a[i], b[i], w[i]);
    		B.Insert(a[i], b[i], w[i]);
    	}
    	cout << "该图的深度优先遍历为:" << endl;
    	A.DFS();
    	cout << endl;
    	cout << "该图的广度优先遍历为:" << endl;
    	A.BFS();
    	cout << endl;
    	cout << "请输入要搜索的边: ";
    	int c, d;
    	cin >> c >> d;
    	if(A.Exist(c, d)) cout << "邻接矩阵中该边存在!" << endl;
    	else cout << "邻接矩阵中该边不存在!" << endl;
    	if(B.Exist(c, d)) cout << "邻接表中该边存在!" << endl;
    	else cout << "邻接表中该边不存在!" << endl;
    	cout << "请输入要删除的边: ";
    	int e, f;
    	cin>> e >> f;
    	if(A.Remove(e, f) == Success) cout << "邻接矩阵中删除该边成功!" << endl;
    	else if(A.Remove(e, f) == NotPresent) cout<<"邻接矩阵中该边不存在!"<<endl;
    	else cout<<"输入错误!"<<endl;
    	if(B.Remove(e, f) == Success) cout << "邻接表中删除该边成功!" << endl;
    	else if(B.Remove(e, f) == NotPresent) cout << "邻接表中该边不存在!" << endl;
    	else cout << "邻接表中输入错误!" << endl;
    	cout << "删除该边后该图的深度优先遍历为:" << endl;
    	A.DFS();
    	cout << endl;
    	cout << "删除该边后该图的广度优先遍历为:" << endl;
    	A.BFS();
    	cout << endl;
    	return 0;
    }


  • 相关阅读:
    SVN tags使用
    switch case执行顺序
    excel 15位身份证转18位
    .net core options 依赖注入的方式
    DICOM 相关概念了解
    Dicom文件基本操作
    asp.net core 3 使用nlog日志组件,使用$ {basedir}保存位置不对,记录下怎么解决
    asp.net core 动态更新 appsetting.json方法
    asp.net core appsetting.json 绑定读取
    centos 安装 nginx 及配置 的坑
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/6933301.html
Copyright © 2011-2022 走看看