linux c界面相关函数,C/C++ 图的创建及图的相关函数(链表法)

图的概念

图由点和线组成

知道了图中有多少个点,和哪些点之间有线,就可以把一张图描绘出来

点之间的线,分有方向和无方向

创建图

创建图,实际就是创建出节点,和节点之间的线。

7bbf7aa549b63ac5ea49a6ead1f9bbe1.png

下面的代码实现了上面的图的创建

graph_link.h

#ifndef __graph_link__

#define __graph_link__

#include

#include

#include

#include

#define default_vertex_size 10

#define T char

//边的结构

typedef struct Edge{

//顶点的下标

int idx;

//指向下一个边的指针

struct Edge* link;

}Edge;

//顶点的结构

typedef struct Vertex{

//顶点的值

T data;

//边

Edge* adj;

}Vertex;

//图的结构

typedef struct GraphLink{

int MaxVertices;

int NumVertices;

int NumEdges;

Vertex* nodeTable;

}GraphLink;

//初始化图

void init_graph_link(GraphLink* g);

//显示图

void show_graph_link(GraphLink* g);

//插入顶点

void insert_vertex(GraphLink* g, T v);

//插入边尾插

void insert_edge_tail(GraphLink* g, T v1, T v2);

//插入边头插

void insert_edge_head(GraphLink* g, T v1, T v2);

//删除边

void remove_edge(GraphLink* g, T v1, T v2);

//删除顶点

void remove_vertex(GraphLink* g, T v);

//销毁图

void destroy_graph_link(GraphLink* g);

//取得指定顶点的第一个后序顶点

int get_first_neighbor(GraphLink* g, T v);

//取得指定顶点v1的临街顶点v2的第一个后序顶点

int get_next_neighbor(GraphLink* g, T v1, T v2);

#endif

graph_link.c

#include "graph_link.h"

//初始化图

void init_graph_link(GraphLink* g){

g->MaxVertices = default_vertex_size;

g->NumVertices = g->NumEdges = 0;

g->nodeTable = (Vertex*)malloc(sizeof(Vertex) * g->MaxVertices);

assert(NULL != g->nodeTable);

for(int i = 0; i < g->MaxVertices; ++i){

g->nodeTable[i].adj = NULL;

}

}

//显示图

void show_graph_link(GraphLink* g){

if(NULL == g)return;

for(int i = 0; i < g->NumVertices; ++i){

printf("%d %c->", i, g->nodeTable[i].data);

Edge* p = g->nodeTable[i].adj;

while(NULL != p){

printf("%d->", p->idx);

p = p->link;

}

printf(" NULL\n");

}

}

//插入顶点

void insert_vertex(GraphLink* g, T v){

if(g->NumVertices >= g->MaxVertices)return;

g->nodeTable[g->NumVertices++].data = v;

}

//查找顶点的index

int getVertexIndex(GraphLink* g, T v){

for(int i = 0; i < g->NumVertices; ++i){

if(v == g->nodeTable[i].data)return i;

}

return -1;

}

//创建边

void buyEdge(Edge** e, int idx){

Edge* p = (Edge*)malloc(sizeof(Edge));

p->idx = idx;

p->link = NULL;

if(NULL == *e){

*e = p;

}

else{

Edge* tmp = *e;

while(tmp->link != NULL){

tmp = tmp->link;

}

tmp->link = p;

}

}

//插入边(尾插)

void insert_edge_tail(GraphLink* g, T v1, T v2){

int p1 = getVertexIndex(g, v1);

int p2 = getVertexIndex(g, v2);

if(p1 == -1 || p2 == -1)return;

buyEdge(&(g->nodeTable[p1].adj), p2);

g->NumEdges++;

buyEdge(&(g->nodeTable[p2].adj), p1);

g->NumEdges++;

}

//插入边(头插)

void insert_edge_head(GraphLink* g, T v1, T v2){

int p1 = getVertexIndex(g, v1);

int p2 = getVertexIndex(g, v2);

if(p1 == -1 || p2 == -1)return;

Edge* p = (Edge*)malloc(sizeof(Edge));

p->idx = p2;

p->link = g->nodeTable[p1].adj;

g->nodeTable[p1].adj = p;

p = (Edge*)malloc(sizeof(Edge));

p->idx = p1;

p->link = g->nodeTable[p2].adj;

g->nodeTable[p2].adj = p;

}

//删除边

int remove_edge_(Edge** p, int i){

if(NULL == *p)return -1;

Edge* f;

//判断第一个边是否是目标边

if((*p)->idx == i){

//删除第一条边

f = *p;

*p = (*p)->link;

free(f);

return 0;

}

Edge* tmp = *p;

while(tmp->link != NULL && tmp->link->idx != i){

tmp = tmp->link;

}

//没有找到边

if(tmp->link == NULL){

return -1;

}

//找到边

else{

f = tmp->link;

tmp->link = tmp->link->link;

free(f);

return 0;

}

}

void remove_edge(GraphLink* g, T v1, T v2){

int p1 = getVertexIndex(g, v1);

int p2 = getVertexIndex(g, v2);

if(p1 == -1 || p2 == -1)return;

int r = remove_edge_(&(g->nodeTable[p1].adj), p2);

if(r == 0){

g->NumEdges--;

remove_edge_(&(g->nodeTable[p2].adj), p1);

g->NumEdges--;

}

}

//删除顶点

void remove_vertex(GraphLink* g, T v){

int p = getVertexIndex(g, v);

if(p == -1)return;

//删除目标顶点以外的顶点,与目标顶点之间的边

for(int i = 0; i < g->NumVertices; ++i){

if(i == p){

continue;

}else{

remove_edge_(&(g->nodeTable[i].adj), p);

}

}

//删除目标顶点行的所有边

Edge* te = g->nodeTable[p].adj;

Edge* tmp;

while(te != NULL){

tmp = te;

te = te->link;

free(tmp);

}

//让被删除顶点那行,指向最后一个顶点那行。

//因为最后一行向上移动了,所以要修改和最后一行有连线的点那行的线的下标。

g->nodeTable[p].data = g->nodeTable[g->NumVertices - 1].data;

g->nodeTable[p].adj = g->nodeTable[g->NumVertices - 1].adj;

tmp = g->nodeTable[p].adj;

Edge* q;

while(tmp != NULL){

q = g->nodeTable[tmp->idx].adj;

while(q != NULL && q->idx != g->NumVertices - 1){

q = q->link;

}

q->idx = p;

tmp = tmp->link;

}

g->NumVertices--;

}

//销毁图

void destroy_graph_link(GraphLink* g){

//释放所有边的内存空间

Edge* t = NULL;

Edge* p = NULL;

for(int i = 0; i< g->NumVertices; ++i){

t = g->nodeTable[i].adj;

while(NULL != t){

p = t;

t = t->link;

free(p);

}

}

//释放所有顶点的内存空间

free(g->nodeTable);

g->nodeTable = NULL;

g->MaxVertices = g->NumVertices = g->NumEdges = 0;

}

//取得指定顶点的第一个后序顶点

int get_first_neighbor(GraphLink* g, T v){

int i = getVertexIndex(g, v);

if (-1 == i)return -1;

Edge* p = g->nodeTable[i].adj;

if(NULL != p)

return p->idx;

else

return -1;

}

//取得指定顶点v1的临街顶点v2的第一个后序顶点

int get_next_neighbor(GraphLink* g, T ve1, T ve2){

int v1 = getVertexIndex(g, ve1);

int v2 = getVertexIndex(g, ve2);

if(v1 == -1 || v2 == -1)return -1;

Edge* t = g->nodeTable[v1].adj;

while(t != NULL && t->idx != v2){

t = t->link;

}

if(NULL != t && t->link != NULL){

return t->link->idx;

}

return -1;

}

graph_linkmain.c

#include "graph_link.h"

int main(){

GraphLink gl;

//初始化图

init_graph_link(&gl);

//插入节点

insert_vertex(&gl, 'A');

insert_vertex(&gl, 'B');

insert_vertex(&gl, 'C');

insert_vertex(&gl, 'D');

insert_vertex(&gl, 'E');

//显示图

//show_graph_link(&gl);

//插入边(尾插)

/*

insert_edge_tail(&gl, 'A', 'B');

insert_edge_tail(&gl, 'A', 'D');

insert_edge_tail(&gl, 'B', 'C');

insert_edge_tail(&gl, 'B', 'E');

insert_edge_tail(&gl, 'C', 'D');

insert_edge_tail(&gl, 'C', 'E');

*/

//插入边(头插)

///*

insert_edge_head(&gl, 'A', 'B');

insert_edge_head(&gl, 'A', 'D');

insert_edge_head(&gl, 'B', 'C');

insert_edge_head(&gl, 'B', 'E');

insert_edge_head(&gl, 'C', 'D');

insert_edge_head(&gl, 'C', 'E');

//*/

//显示图

show_graph_link(&gl);

printf("\n");

//删除边

remove_edge(&gl, 'A', 'D');

//显示图

show_graph_link(&gl);

printf("\n");

//删除顶点

remove_vertex(&gl, 'C');

//显示图

show_graph_link(&gl);

//临街顶点的下标

int v = get_first_neighbor(&gl, 'B');

printf("%d\n", v);

v = get_next_neighbor(&gl, 'B', 'A');

printf("%d\n", v);

//销毁图

destroy_graph_link(&gl);

}

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值