肯定有很多bug,但不太想找了
自己存着备用
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int Max = 1e7;
struct EBox
{
bool mark;
int ivex, jvex;
EBox* ilink, * jlink;
int info;
};
struct VexBox
{
bool visited;
char data;
EBox* firstrdge;
};
struct TNode
{
char data;
int length;
TNode* firstkid, *brother;
};
class C_BTree
{
private:
int nodenum;
TNode* DFS(TNode* p, char data);
void DFST(TNode* q);
TNode root;
public:
int size() { return nodenum; }
C_BTree(char name=0);
TNode* DFSearch(char data);
friend class AMLGraph;
void DFSTraversal();
};
bool EdgeSort(EBox* p, EBox* q);
class AMLGraph
{
private:
vector<VexBox> adjmulist;
int vexnum, edgenum;//顶点数 边数
void DFS(int v);
EBox* FirstAdjVex(int v);
EBox* NextAdjVex(int v, EBox* w);
void Resetvisited();
friend bool EdgeSort(EBox* p, EBox* q);
public:
AMLGraph();
int Locate(char a);
void DFSTraverse();
void BFTraverse();
bool Dijkstra(char begin, vector<int>& dist);
int edgeinfo(int a, int b);
C_BTree* Prim(char root,C_BTree *T=NULL);
bool SPFA(char begin, vector<int>& dist);
C_BTree* Kruskal(char root, C_BTree* T = NULL);
};
int main()
{
AMLGraph G;
C_BTree *T=NULL,*S=NULL;
}
AMLGraph::AMLGraph()
{
cout << "输入顶点数和边数:";
cin >> vexnum >> edgenum;
VexBox t;
t.data = 0;
t.firstrdge = NULL;
adjmulist.resize(vexnum, t);
for (int i = 0; i < vexnum; i++)
{
cout << "输入顶点信息(char)";
cin >> adjmulist[i].data;
}
Resetvisited();
for (int i = 0; i < edgenum; i++)
{
cout << "输入边的两个结点(char)和边信息(int)";
char a, b;
EBox* temp = new EBox(), * p;
temp->mark = false;
cin >> a >> b >> temp->info;
temp->ivex = Locate(a);
temp->jvex = Locate(b);
p = adjmulist[temp->ivex].firstrdge;
adjmulist[temp->ivex].firstrdge = temp;
temp->ilink = p;
p = adjmulist[temp->jvex].firstrdge;
adjmulist[temp->jvex].firstrdge = temp;
temp->jlink = p;
}
}
int AMLGraph::Locate(char a)
{
for (int i = 0; i < vexnum; i++)
{
if (a == adjmulist[i].data)return i;
}
return -1;
}
void AMLGraph::DFSTraverse()
{
for (int i = 0; i < vexnum; i++)
if (!adjmulist[i].visited)DFS(i);
Resetvisited();
}
void AMLGraph::DFS(int v)
{
adjmulist[v].visited = true;
cout << adjmulist[v].data << endl;
for (EBox* w = FirstAdjVex(v); w != NULL; w = NextAdjVex(v, w))
{
int wvex;
if (w->ivex == v)wvex = w->jvex;
else wvex = w->ivex;
if (!adjmulist[wvex].visited)DFS(wvex);
}
}
EBox* AMLGraph::FirstAdjVex(int v)
{
return adjmulist[v].firstrdge;
}
EBox* AMLGraph::NextAdjVex(int v, EBox * w)
{
if (w->ivex == v)return w->ilink;
else return w->jlink;
}
void AMLGraph::Resetvisited()
{
for (int i = 0; i< adjmulist.size(); i++)
adjmulist[i].visited = false;
}
void AMLGraph::BFTraverse()
{
queue<int> Q;
for (int i = 0; i < adjmulist.size(); i++)
{
if (!adjmulist[i].visited)
{
adjmulist[i].visited = true;
Q.push(i);
}
while (!Q.empty())
{
int i = Q.front();
cout << adjmulist[i].data << endl;
Q.pop();
for (EBox* w = FirstAdjVex(i); w != NULL; w = NextAdjVex(i, w))
{
int t;
if (w->ivex == i)t = w->jvex;
else t = w->ivex;
if(!adjmulist[t].visited)
{
adjmulist[t].visited = true;
Q.push(t);
}
}
}
}
Resetvisited();
}
bool AMLGraph::Dijkstra(char begin ,vector<int>& dist)
{
dist.clear();
const int n = adjmulist.size();
int v = Locate(begin);
if (v == -1)return false;
dist.resize(n,Max);
dist[v] = 0;
for (EBox* w = FirstAdjVex(v); w != NULL; w = NextAdjVex(v, w))
{
int t;
if (w->ivex ==v)t = w->jvex;
else t = w->ivex;
dist[t] = w->info;
}
adjmulist[v].visited = true;
for (int i = 0; i < n; i++)
{
int temp = Max;
int u = v;
//寻找下一个从起始点开始最近的点
for (int j = 0; j < n; j++)
{
if (!adjmulist[j].visited && dist[j] < temp)
{
u = j;
temp = dist[j];
}
}
//找到
adjmulist[u].visited = true;
//加入这个点后所引起的起始点距未加入点的距离的变化
for (int j = 0; j <n; j++)
{
int t = edgeinfo(u, j);
if (!adjmulist[j].visited && (dist[u] + t < dist[j]))
{
dist[j] = dist[u] + t;
//prev[j]=u;
}
}
}
Resetvisited();
return true;
}
int AMLGraph::edgeinfo(int u, int j)
{
for (EBox* w = FirstAdjVex(u); w != NULL; w = NextAdjVex(u, w))
{
if ((w->ivex == u && w->jvex == j) || (w->jvex == u && w->ivex == j))return w->info;
}
return Max;
}
bool AMLGraph::SPFA(char begin, vector<int>& dist)//无向图中不应存在负权
{
dist.clear();
queue<int> Q;
const int n = adjmulist.size();
int v = Locate(begin);
if (v == -1)return false;
dist.resize(n, Max);
dist[v] = 0;
adjmulist[v].visited = true;
Q.push(v);
while (!Q.empty())
{
int k = Q.front();
Q.pop();
adjmulist[k].visited = false;
for (EBox* w = FirstAdjVex(k); w != NULL; w = NextAdjVex(k, w))
{
int y;
if (w->ivex == k)y = w->jvex; else y = w->ivex;
if (dist[y] > dist[k] + w->info)
{
dist[y] = dist[k] + w->info;
if (!adjmulist[y].visited)
{
Q.push(y);
adjmulist[y].visited = true;
}
}
}
}
return true;
Resetvisited();
}
C_BTree* AMLGraph::Prim(char root, C_BTree *T)
{
if (T != NULL) { delete T; }
T = new C_BTree(root);
vector<int> length;
length.resize(adjmulist.size(),Max);//记录每个节点到树的距离,入树设为0
length[Locate(root)] = 0;
const int n = adjmulist.size();
while (T->size() != n)
{
for (int i = 0; i < n; i++)
{
if(length[i]!=0)//i节点一定未入树
for (EBox* w = FirstAdjVex(i); w != NULL; w = NextAdjVex(i, w))
if (length[w->jvex] == 0|| length[w->ivex] == 0)//i节点的相邻节点在树中
{
if (length[i] > w->info)length[i] = w->info;
}
}
int minnode = -1,min=Max;
for (int i = 0; i < n; i++)
{
if (length[i] != 0 && length[i] < min)
{
min = length[i];
minnode = i;
}
}
char fathe;
for (EBox* w = FirstAdjVex(minnode); w != NULL; w = NextAdjVex(minnode, w))
{
if (w->info == min)
{
if (w->ivex == minnode)fathe = adjmulist[w->jvex].data;
else fathe = adjmulist[w->ivex].data;
break;
}
}
TNode* temp = T->DFSearch(fathe);
TNode* p= new TNode;
p->data = adjmulist[minnode].data;
p->length = min;
p->firstkid = p->brother = NULL;
if (temp->firstkid == NULL)temp->firstkid = p;
else
{
temp = temp->firstkid;
while (temp->brother != NULL)
temp = temp->brother;
temp->brother = p;
}
T->nodenum++;
length[minnode] = 0;
}
return T;
}
C_BTree* AMLGraph::Kruskal(char root, C_BTree* T)
{
struct E {
int n, m,length;
};
if (T != NULL) delete T;
T = new C_BTree();
const int n = adjmulist.size();
vector<TNode*> point;//生成树节点
vector<EBox*> edges;//记录最短边
vector<int>roots;//记录集合
vector<E> Branch;//记录树枝
for (int i = 0; i < n; i++)//初始化集合
{
roots.push_back(i);
}
for (int i = 0; i < n; i++)//初始化树节点
{
TNode* temp=new TNode;
temp->data = adjmulist[i].data;
temp->brother = temp->firstkid= NULL;
temp->length = 0;
point.push_back(temp);
}
for (int i = 0; i < n; i++)//初始化边
{
for (EBox* w = FirstAdjVex(i); w != NULL; w = NextAdjVex(i, w))
{
if (w->mark == false)
{
edges.push_back(w);
w->mark = true;
}
}
}
const int m = edges.size();
sort(edges.begin(), edges.end(), EdgeSort);
int k= 0,j=0;
while (k < n-1&&j<m)
{
int m1 = edges[j]->ivex;
int m2 = edges[j]->jvex;
if (roots[m1]!=roots[m2])
{
k++;
{
E temp;
temp.m = m1;
temp.n = m2;
temp.length = edges[j]->info;
Branch.push_back(temp);
}
int te = roots[m2];
for (int i = 0; i < roots.size(); i++)//合并集合
if (roots[i] == te)roots[i] = roots[m1];
}
j++;
}
int rootn = Locate(root);
T->root = *(point[rootn]);
T->nodenum = 1;
adjmulist[rootn].visited = true;
while (T->nodenum < n)
{
for (int i = 0; i < Branch.size()&& T->nodenum < n; i++)
{
int m1 = Branch[i].m;
int m2 = Branch[i].n;
TNode* fa=NULL,*ch=NULL;
if (adjmulist[m1].visited)
{
fa=T->DFSearch(adjmulist[m1].data);
point[m2]->length = Branch[i].length;
ch = point[m2];
adjmulist[m2].visited = true;
}
else if(adjmulist[m2].visited)
{
fa = T->DFSearch(adjmulist[m2].data);
point[m1]->length = Branch[i].length;
ch = point[m1];
adjmulist[m1].visited = true;
}
if (fa!=NULL)
{
if (fa->firstkid==NULL)
{
fa->firstkid = ch;
}
else
{
fa = fa->firstkid;
while (fa->brother != NULL)fa = fa->brother;
fa->brother = ch;
}
T->nodenum++;
Branch.erase(Branch.begin() + i);
}
}
}
for (int i = 0; i < m; i++)
{
edges[i]->mark = false;
}
return T;
Resetvisited();
}
C_BTree::C_BTree(char name)
{
if (name == 0)
nodenum = 0;
else
nodenum = 1;
root.data = name;
root.firstkid = root.brother = NULL; root.length = Max;
}
TNode* C_BTree::DFSearch(char data)
{
if (root.data == data)return &root;
TNode* q = DFS(root.firstkid, data);
return q;
}
TNode* C_BTree::DFS(TNode* p, char data)
{
TNode* temp=NULL;
if (p->data == data) {
temp = p;
}
if (temp == NULL && p->firstkid != NULL) {
temp = DFS(p->firstkid, data);
}
if (temp == NULL && p->brother != NULL){
temp=DFS(p->brother, data);
}
return temp;
}
void C_BTree::DFSTraversal()
{
DFST(&root);
}
void C_BTree::DFST(TNode* q)
{
cout << q->data<<" ";
if (q->firstkid != NULL)DFST(q->firstkid);
if(q->brother != NULL)DFST(q->brother);
}
bool EdgeSort(EBox* p, EBox* q)
{
return p->info < q->info;
}