目录
一、图的邻接矩阵
存储结构
顶点数组:存储顶点数据
边数组:存储边数据
typedef struct
{
char vertex[MAXSIZE]; //顶点
int edge[MAXSIZE][MAXSIZE]; //邻接顶点
int vertexNum; //顶点数量
}Graph;
Graph G;
总代码
//无/有向图的邻接矩阵
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define MAXSIZE 20
typedef struct
{
char vertex[MAXSIZE]; //顶点
int edge[MAXSIZE][MAXSIZE]; //邻接顶点
int vertexNum; //顶点数量
}Graph;
Graph G;
//输入顶点
void InputVertex()
{
int i = 0;
char ch;
printf("请输入需要创建的图顶点(不需要空格):\n");
do
{
scanf("%c", &ch);
if (ch != '\n')
G.vertex[i++] = ch;
} while (ch != '\n');
G.vertexNum = i;
}
//查找(根据结点找索引)
int findIndex(char ch)
{
int i;
for (i = 0; i < G.vertexNum; i++)
{
if (G.vertex[i] == ch)
return i;
}
return -1; //没找到
}
//创建图
void InputEdge()
{
int i, index;
char ch;
for (i = 0; i < G.vertexNum; i++)
{
printf("请输入%c指向的邻接结点:\n", G.vertex[i]);
scanf("%c", &ch);
while (ch != '\n')
{
index = findIndex(ch); //查找输入结点的索引
G.edge[i][index] = 1;
scanf("%c", &ch);
}
}
}
//输出测试
void Print()
{
int i, j;
for (i = 0; i < G.vertexNum; i++)
{
printf("\n%c结点的邻接结点为:\t", G.vertex[i]);
for (j = 0; j < G.vertexNum; j++)
{
if (G.edge[i][j] != 0)
printf("%c\t", G.vertex[j]);
}
}
}
int main()
{
//创建图
InputVertex();
InputEdge();
//输出测试
Print();
return 0;
}
二、网图的邻接矩阵
存储结构
顶点数组:存储顶点数据
边数组:存储边数据
网图与图相比多了一个“权”,可以理解为距离。
边数组中对角线为0:因为对角线表示的是指向自身,自身到自身的距离自然是0。
到其他相邻结点距离为:权。
到其他不相邻结点距离为:无穷大(可以用计算机允许的尽可能大的数据代替无穷大)。
总代码
//邻接矩阵(无向网图)
#include<iostream>
#include<stdio.h>
using namespace std;
#define MAXSIZE 20
#define MAX 65535 //无穷大
typedef struct Graph
{
char vertex[MAXSIZE]; //顶点
int arc[MAXSIZE][MAXSIZE]; //边 (权存放在其中)
int numVertex, numArc; //顶点数、边数
}Graph;
Graph G;
void Input()
{
cout << "请输入需要创建的顶点数量和边的数量:\n";
cin >> G.numVertex >> G.numArc;
}
//初始化
void Init_Graph()
{
int i, j;
//给数组赋0
for (i = 0; i < G.numVertex; i++)
{
for (j = 0; j < G.numVertex; j++)
{
G.arc[i][j] = MAX; //先把所有元素赋为无穷大
}
G.arc[i][i] = 0; //对角线元素
}
}
//创建无向图
void CreateGraph()
{
int i, j, num, index = 0;
for (i = 0; i < G.numVertex; i++)
{
printf("请输入第%d个结点及相邻结点数量:\n", i + 1);
getchar();
cin >> G.vertex[i] >> num;
if (num > 0)
printf("请分别输入相邻结点下标和权(空格分隔):\n", num);
for (j = 0; j < num; j++)
{
getchar();
cin >> index;
cin >> G.arc[i][index];
}
}
}
//遍历
void Traverse()
{
int i, j;
for (i = 0; i < G.numVertex; i++)
{
for (j = 0; j < G.numVertex; j++)
printf("%d\t", G.arc[i][j]);
cout << endl;
}
}
int main()
{
Input();
Init_Graph();
CreateGraph(); //创建
Traverse(); //遍历
return 0;
}
三、图的邻接表
存储结构
无向图邻接表:
有向图邻接表:
1、顶点列表结构体
//顶点列表
typedef struct VertexList
{
int index; //索引
char data; //数据
EdgeNode* firstedge; //指向第一个邻接结点
}VertexList;
VertexList L[MAXSIZE];
2、邻接顶点结构体
//邻接顶点
typedef struct EdgeNode
{
int index; //邻接结点索引
char data; //邻接结点数据
struct EdgeNode* next; //指向下一个邻接结点
}EdgeNode;
总代码
//图的邻接表
#include<stdio.h>
#include<iostream>
#include<malloc.h>
using namespace std;
#define MAXSIZE 100
int listLength = 0;
//邻接顶点
typedef struct EdgeNode
{
int index; //邻接结点索引
char data; //邻接结点数据
struct EdgeNode* next; //指向下一个邻接结点
}EdgeNode;
//顶点列表
typedef struct VertexList
{
int index; //索引
char data; //数据
EdgeNode* firstedge; //指向第一个邻接结点
}VertexList;
VertexList L[MAXSIZE];
//输入
void Input()
{
int i = 0;
char ch = ' ';
cout << "请输入需要创建的结点:\n";
scanf_s("%c", &ch, 1);
for (i = 0; i < MAXSIZE && ch != '\n'; i++)
{
L[i].data = ch;
scanf_s("%c", &ch, 1);
}
listLength = i; //获取列表长度(吸收空格)
}
void InitList()
{
int i;
for (i = 0; i < listLength; i++)
L[i].firstedge = NULL;
}
//查找
int find(char ch)
{
int i;
for (i = 0; i < listLength; i++)
{
if (ch == L[i].data)
return ch;
}
return NULL;
}
//初始化列表
void Create_List()
{
int i;
char ch, choice;
EdgeNode* N = NULL;
for (i = 0; i < listLength; i++)
{
printf("%c是否有邻接结点?(Y/N)\n", L[i].data);
scanf_s("%c", &choice, 1);
getchar();
if (choice == 'y' || choice == 'Y')
{
L[i].firstedge = (EdgeNode*)malloc(sizeof(EdgeNode));
N = (EdgeNode*)malloc(sizeof(EdgeNode));
N = L[i].firstedge; //连接
printf("请输入%c的邻接结点:\n", L[i].data);
while (1)
{
scanf_s("%c", &ch, 1);
if (ch == '\n')
break;
else if (ch == ' ')
continue;
N->data = ch; //值
N->index = find(ch); //查找并赋值索引
N->next = (EdgeNode*)malloc(sizeof(EdgeNode)); //下一个
N = N->next;
}
N->next = NULL;
}
}
}
void Print()
{
int i;
EdgeNode* N = NULL;
for (i = 0; i < listLength; i++)
{
printf("\n%c的邻接结点:", L[i].data);
N = L[i].firstedge;
while (N)
{
cout << N->data;
N = N->next;
}
cout << endl;
}
}
int main()
{
Input();
InitList();
Create_List();
Print();
return 0;
}
四、网图的邻接表
存储结构
1、顶点列表结构体
//结点列表
typedef struct NodeList
{
char data;
int length;
EdgeNode* firstEdge;
}NodeList;
NodeList L[MAXSIZE];
2、邻接顶点结构体
//邻接结点
typedef struct EdgeNode
{
int index;
char data;
int weight; //权重
struct EdgeNode* next;
}EdgeNode, * pEdgeNode; //*pEdgeNode后面为创建二级指针
总代码
//网图的邻接表
//运用了二级指针:要直接修改地址需要用到二级指针
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<malloc.h>
using namespace std;
#define MAXSIZE 100
int length = 0;
//邻接结点
typedef struct EdgeNode
{
int index;
char data;
int weight; //权重
struct EdgeNode* next;
}EdgeNode, * pEdgeNode; //*pEdgeNode后面为创建二级指针
//结点列表
typedef struct NodeList
{
char data;
int length;
EdgeNode* firstEdge;
}NodeList;
NodeList L[MAXSIZE];
//输入并初始化
void Input_Init()
{
int i = 0;
char ch = ' ';
printf("请输入需要创建的结点:\n");
while (ch != '\n') //(这里其实用do while()会更好)
{
scanf_s("%c", &ch);
L[i].data = ch;
L[i].firstEdge = NULL;
i++;
}
length = i - 1; //包括了换行符
printf("请分别输入这%d个结点的邻接结点的数量:\n", length);
for (i = 0; i < length; i++)
{
scanf("%d", &L[i].length);
}
}
//获取索引
int findIndex(char ch)
{
int i = 0;
for (i = 0; i < length; i++)
{
if (ch == L[i].data)
return i;
}
return -1;
}
//创建列表
void CreateList()
{
int i, j, weight;
char ch = ' ';
pEdgeNode* N = NULL; //----------------------二级指针--------------------//
for (i = 0; i < length; i++)
{
if (ch != '\n') //创建首
{
L[i].firstEdge = (EdgeNode*)malloc(sizeof(EdgeNode));
//-----------------二级指针---------------//
N = (pEdgeNode*)malloc(sizeof(pEdgeNode));
N = &L[i].firstEdge;
}
printf("请分别输入%c结点的邻接结点和权重:\n", L[i].data);
for (j = 0; j < L[i].length; j++)
{
getchar();
scanf("%c %d", &ch, &weight);
if (ch == ' ') //空格不计
{
j--;
continue;
}
//-----------------二级指针操作---------------//
(*N)->index = findIndex(ch); //获取索引
if ((*N)->index != -1) //有该元素
{
(*N)->data = ch; //赋值
(*N)->weight = weight; //权重
(*N)->next = (EdgeNode*)malloc(sizeof(EdgeNode)); //创建next指针
N = &((*N)->next); //后移(指向next指针的地址)(注:next也为二级指针时不行,不知道为什么)
}
}
(*N) = NULL; //----------地址置空,用到了二级指针----------//
}
}
//遍历
void Print()
{
int i = 0, j;
pEdgeNode* N;
for (i = 0; i < length; i++)
{
N = &L[i].firstEdge;
printf("\n%c结点邻接结点:\n", L[i].data);
while ((*N) != NULL)
{
printf("%c权重:%d\n", (*N)->data, (*N)->weight);
N = &((*N)->next);
}
}
}
int main()
{
Input_Init();
CreateList();
Print();
return 0;
}