永发信息网

用无向图的邻接矩阵实现边的插入和删除、顶点的插入和删除

答案:1  悬赏:0  手机版
解决时间 2021-04-28 04:20

用数据结构C语言编写

最佳答案
复制粘贴即可
#include <iostream>
using namespace std;



//*****stack.h
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
template<class QElemType>
class stack
{
public:
void InitStack();
void DestroyStack();
void ClearStack();
Status StackEmpty();
Status StackLength();
void GetTop(QElemType & e);
void Push(QElemType e);
void Pop(QElemType & e);
private:
struct SqStack{
QElemType *base;
QElemType *top;
int stacksize;
}S;
};
//******stack.cpp------
template<class QElemType>
void stack<QElemType>::InitStack()
{
S.base = (QElemType *)malloc(STACK_INIT_SIZE * sizeof(QElemType));
if(!S.base) exit(0);
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
}
template <class QElemType>
void stack<QElemType>::DestroyStack()
{
free(S.base);
}
template <class QElemType>
void stack<QElemType>::ClearStack()
{
S.top = S.base;
}
template <class QElemType>
Status stack<QElemType>::StackEmpty()
{
if(S.top == S.base) return 1;
else return 0;
}
template <class QElemType>
Status stack<QElemType>::StackLength()
{
return (S.top - S.base);
}
template <class QElemType>
void stack<QElemType>::GetTop(QElemType & e)
{
if(S.top != S.base)
e = *(S.top - 1);
else cout << "ERROR" << endl;
}
template <class QElemType>
void stack<QElemType>::Push(QElemType e)
{
if(S.top - S.base >= S.stacksize)
{
S.base = (QElemType *)realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(QElemType));
if(!S.base) exit(0);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top++ = e;
}
template <class QElemType>
void stack<QElemType>::Pop(QElemType & e)
{
if(S.top == S.base) cout << "ERROR" << endl;
else
e = * --S.top;
}
//**********stack.cpp End






template <class TElemType>
class Graph
{
public:
void CreateUDN();
void DestroyUDN();
void CreateAlgraph();
void DestroyAlgraph();
void DFS(int v,bool *visited);
void DFSTraverse();
void Minispantree_prim(); //PRIM算法求最小生成树
void Shortestpath_DIJ(TElemType data1,TElemType data2); //对环不适用,如从V1到V1就不适用
void Shortestpath_FLOYD(TElemType data1,TElemType data2);
private:
template <class TElemType>
struct Mgraph{
int vexnum;
int arcnum;
TElemType *vertex;
int **AdjMatrix;
};
Mgraph<TElemType> gph; //邻接矩阵存储
struct Arcnode
{
int adjvex;
Arcnode *nextarc;
float weight;
};

template <class TElemType>
struct Vexnode
{
TElemType data;
Arcnode *firarc;
};
struct ALgraph
{
int vexnum;
int arcnum;
bool kind;
Vexnode<TElemType> *vex;
};
ALgraph algraph; //邻接表存储
};


//*********Graph.cpp
template <class TElemType>
void Graph<TElemType>::CreateUDN()
{
cout << "输入无向网的顶点数和边数:" << endl;
cin >> gph.vexnum >> gph.arcnum;
gph.vertex = (TElemType *)malloc(gph.vexnum * sizeof(TElemType));
int i,j,m,n; //m,n表示顶点信息对应的序号,w是权值
int w;
TElemType v1,v2;
cout << "输入顶点信息:" << endl;
for(i = 0;i < gph.vexnum;i++)
cin >> gph.vertex[i];
gph.AdjMatrix = (int **)malloc(gph.vexnum * sizeof(int *));
for(i = 0;i < gph.vexnum;i++)
gph.AdjMatrix[i] = (int *)malloc(gph.vexnum * sizeof(int));
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
gph.AdjMatrix[i][j] = INT_MAX; //INT_MAX
cout << "输入一条边依附的两点及权值:" << endl;
for(int k = 0;k < gph.arcnum;k++)
{
cin >> v1 >> v2 >> w;
for(i = 0;i < gph.vexnum;i++)
{
if(v1 == gph.vertex[i]) m = i;
if(v2 == gph.vertex[i]) n = i;
}
gph.AdjMatrix[m][n] = gph.AdjMatrix[n][m] = w;
}
}


template <class TElemType>
void Graph<TElemType>::DestroyUDN()
{
free(gph.vertex);
for(int i = 0;i < gph.vexnum;i++)
free(gph.AdjMatrix[i]);
free(gph.AdjMatrix);
}

template <class TElemType>
void Graph<TElemType>::CreateAlgraph()
{
int i,j,m,n;
float w;
TElemType v1,v2;
Arcnode *p;
cout << "输入图类型(1是无向图,0是有向图):" << endl;
cin >> algraph.kind;
cout << "输入顶点数和边数:" << endl;
cin >> algraph.vexnum >> algraph.arcnum;
algraph.vex = (Vexnode<TElemType> *)malloc(algraph.vexnum * sizeof(Vexnode<TElemType>));
cout << "输入顶点信息:" << endl;
for(i = 0;i < algraph.vexnum;i++)
{
cin >> algraph.vex[i].data;
algraph.vex[i].firarc = NULL;
}

if(algraph.kind)
{
cout << "输入各边依附的两点和权值:" << endl;
for(i = 0;i < algraph.arcnum;i++)
{
cin >> v1 >> v2 >>w;
for(j = 0;j < algraph.vexnum;j++)
{
if(v1 == algraph.vex[j].data) m = j;
if(v2 == algraph.vex[j].data) n = j;
}
p = (Arcnode *)malloc(2*sizeof(Arcnode));
p[0].adjvex = n;p[0].weight = w;
p[1].adjvex = m;p[1].weight = w;
p[0].nextarc = algraph.vex[m].firarc;algraph.vex[m].firarc = p;
p[1].nextarc = algraph.vex[n].firarc;algraph.vex[n].firarc = ++p;
}
}

else
{
cout << "输入各边的弧尾与弧头结点及有向边的权值:" << endl;
for(i = 0;i < algraph.arcnum;i++)
{
cin >> v1 >> v2 >> w;
for(j = 0;j < algraph.vexnum;j++)
{
if(v1 == algraph.vex[j].data) m = j;
if(v2 == algraph.vex[j].data) n = j;
}
p = (Arcnode *)malloc(sizeof(Arcnode));
p->adjvex = n;p->weight = w;
p->nextarc = algraph.vex[m].firarc;algraph.vex[m].firarc = p;
}
}
} //构造完成


template <class TElemType>
void Graph<TElemType>::DestroyAlgraph()
{
int i;
Arcnode *p,*q;
for(i = 0;i < algraph.vexnum;i++)
{
p = algraph.vex[i].firarc;
if(p)
{
q = p->nextarc;
while(q)
{
free(p);
p = q;
q = q->nextarc;
}
free(p);
}
}
free(algraph.vex);
}

template <class TElemType>
void Graph<TElemType>::DFS(int v,bool *visited)
{
cout << algraph.vex[v].data << endl;
visited[v] = true;
Arcnode *p;
int v1;
for(p = algraph.vex[v].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(!visited[v1]) DFS(v1,visited);
}
}

template <class TElemType>
void Graph<TElemType>::DFSTraverse()
{
int i,v;
bool *visited = (bool *)malloc(algraph.vexnum * sizeof(bool));
for(i = 0;i < algraph.vexnum;i++)
visited[i] = false;
for(v = 0;v < algraph.vexnum;v++)
if(!visited[v]) DFS(v,visited);
free(visited);
} //EndDFSTraverse

template <class TElemType>
void Graph<TElemType>::Minispantree_prim()
{
struct closedge
{
int adjvex;
int lowcost;
};
closedge *edge = (closedge *)malloc(gph.vexnum * sizeof(closedge));
int i,j,k = 0,u;
int min;
for(i = 0;i < gph.vexnum;i++)
{
if(i != k)
{
edge[i].adjvex = 0;
edge[i].lowcost = gph.AdjMatrix[k][i];
}
}
edge[k].lowcost = 0;
cout << "最小生成树的边如下:" << endl;
for(i = 1;i < gph.vexnum;i++)
{
min = INT_MAX;
for(j = 0;j < gph.vexnum;j++)
if(edge[j].lowcost != INT_MAX &&edge[j].lowcost != 0 && edge[j].lowcost < min)
{
min = edge[j].lowcost;
k = j;
}
u = edge[k].adjvex;
edge[k].lowcost = 0;
cout << "(" << gph.vertex[u] << "," << gph.vertex[k] << ")" << " ";
for(j = 0;j < gph.vexnum;j++)
if(gph.AdjMatrix[j][k] < edge[j].lowcost)
{
edge[j].lowcost = gph.AdjMatrix[j][k];
edge[j].adjvex = k;
}
}
free(edge);
cout << endl;
}

template <class TElemType>
void Graph<TElemType>::Shortestpath_DIJ(TElemType data1,TElemType data2)
{
int i,j,v,u,k,min;
stack<int> S;
S.InitStack();
int *spath = (int *)malloc(gph.vexnum * sizeof(int));
int *pathrecord = (int *)malloc(gph.vexnum * sizeof(int));
bool *visited = (bool *)malloc(gph.vexnum * sizeof(bool));
for(i = 0;i < gph.vexnum;i++) visited[i] = false;
for(i = 0;i < gph.vexnum;i++)
{
if(data1 == gph.vertex[i]) v = i;
if(data2 == gph.vertex[i]) u = i;
}
for(i = 0;i < gph.vexnum;i++)
{
spath[i] = gph.AdjMatrix[v][i];
pathrecord[i] = v;
}
spath[v] = 0;visited[v] = true;pathrecord[v] = -1;
for(i = 1;i < gph.vexnum;i++)
{
min = INT_MAX;
for(j = 0;j < gph.vexnum;j++)
{
if(!visited[j])
{
if(spath[j] < min) {min = spath[j];k = j;}
}
}
visited[k] = true;
for(j = 0;j < gph.vexnum;j++)
if(!visited[j] && gph.AdjMatrix[k][j] < INT_MAX && spath[k]+gph.AdjMatrix[k][j] < spath[j])
{
spath[j] = spath[k]+gph.AdjMatrix[k][j];
pathrecord[j] = k;
}
}
free(visited);
cout << spath[u] << endl;
S.Push(u);
for(v = pathrecord[u];v != -1;v = pathrecord[v])
S.Push(v);
while(!S.StackEmpty())
{
S.Pop(i);
cout << gph.vertex[i] << " ";
}
cout << endl;
S.DestroyStack();
free(spath);
free(pathrecord);
}


template <class TElemType>
void Graph<TElemType>::Shortestpath_FLOYD(TElemType data1,TElemType data2)
{
int i,j,k,v,u,m;
int **D = (int **)malloc(gph.vexnum * sizeof(int *));
bool ***path = (bool ***)malloc(gph.vexnum * sizeof(bool **));
for(i = 0;i < gph.vexnum;i++)
{
D[i] = (int *)malloc(gph.vexnum * sizeof(int));
path[i] = (bool **)malloc(gph.vexnum * sizeof(bool *));
if(data1 == gph.vertex[i]) v = i;
if(data2 == gph.vertex[i]) u = i;
}
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
path[i][j] = (bool *)malloc(gph.vexnum *sizeof(bool));
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
{
D[i][j] = gph.AdjMatrix[i][j];
for(k = 0;k < gph.vexnum;k++)
path[i][j][k] = false;
if(D[i][j] < INT_MAX)
{
path[i][j][i] = true;path[i][j][j] = true;
}
}
for(k = 0;k < gph.vexnum;k++)
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
if(D[i][k] != INT_MAX && D[k][j] != INT_MAX && D[i][k]+D[k][j] < D[i][j])
{
D[i][j] = D[i][k] + D[k][j];
for(m = 0;m < gph.vexnum;m++)
path[i][j][m] = path[i][k][m] || path[k][j][m];
}
cout << "从" << gph.vertex[v] << "到" << gph.vertex[u] << "的最短路径及经过的点如下:" << endl;
cout << D[v][u] << endl;
for(i = 0;i < gph.vexnum;i++)
if(path[v][u][i] == true) cout << i << " ";
cout << endl;
for(i = 0;i < gph.vexnum;i++)
{
free(D[i]);
free(path[i]);
}
free(D);
free(path);
}

//***********end Graph



int main()
{
Graph<int> gph;
gph.CreateUDN();
gph.Minispantree_prim();
int data1,data2;
cout << "输入起点和终点:" << endl;
cin >> data1 >> data2;

gph.Shortestpath_DIJ(data1,data2);
//gph.Shortestpath_FLOYD(data1,data2);
gph.DestroyUDN();
return 0;
}
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
你会打五笔?
我能长到多高
声桥助听器NO.108这个地址在什么地方,我要处
谁有专打韩版家族战的群号?
描述二十岁女像足球的句子
给某电动车充电,充满需要5度照明电,如果用
爱迪生是发明家还是科学家?
我该怎么办,我这样子很矛盾.......
南京公交学生票年检过了怎么办
Lady gaga有几个男朋友?
天书奇谈真气精华做什么的
Y2828是什么手机品牌?
用友U8系统为什么盘点单显示的账面数量与现存
DNF四川2雷光魔杖多少钱
头发染烫多了,是不是长大成秃头??
推荐资讯
电脑上这是什么东西有什么用?
为什么我炫舞登不上去了
庙台上地址在什么地方,想过去办事
刚买的飞利浦42寸液晶电视总是在凤凰卫视和阳
绿都茶庄地址有知道的么?有点事想过去
《斯琴高丽的伤心》里歌词有这么一句“听说好
我喂了一对虎皮鹦鹉它们孵化出来的小儿为什么
DNF有谁在西南2的啊!
初二数学题 水与我们日常生活密不可分的一个
褒义的骄傲的句子,我能按要求写句子。用骄傲
555~ 51233~2~ ~111~ 16(低音)23~353~~ 555
画画要掌握的要素
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?