非线性结构——图
来源:互联网 发布:淘宝试用规则 编辑:程序博客网 时间:2024/06/05 03:22
图的表示
表示图的方法通常有矩阵,邻接表,十字链表和邻接多重表。其中十字链表是有向图的一种链式存储结构,邻接多重表是无向图的一种链式存储结构。本篇文章主要就以邻接表为例,如下图:
图的遍历
通常图的遍历有两种:深度优先和广度优先。
深度优先遍历是树的先根遍历的推广,它的基本思想是:从图G的某个顶点开始,选择一个与起始顶点相邻且没被访问过的顶点Vi进行访问,再从Vi出发选择一个与Vi相邻且未被访问的顶点Vj进行访问,直到所有相邻顶点都已被访问,则退回到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点,直到图中所有顶点都被访问。简而言之就是一条路走到底,走不通就回到上一个选择点。
广度优先遍历是树的按层次遍历的推广,它的基本思想和层次遍历类似,这里不加赘述。
代码
#include <stdio.h>#include <stdlib.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2#define MAX_NUM 20typedef int Status;typedef int QElemType;typedef char VexType;/* * 邻接表存储结构 */typedef struct EdgeNode{ int adjvex; //顶点在AdjList[]中的位置 struct EdgeNode *next; //指向下一条边的指针}EdgeNode, *EdgeLink;typedef struct VexNode{ VexType data; //顶点值 EdgeNode *firstEdge; //指向第一条边的指针}VexNode, AdjList[MAX_NUM];typedef struct{ AdjList adjList; int vexNum, edgeNum; //顶点数和边数}ALGraph;/* * 队列存储结构(用于图的遍历) */typedef struct QNode{ QElemType data; //结点数据 struct QNode *next; //指向下一个结点}QNode, *QueuePtr;typedef struct{ QueuePtr front; //队头指针 QueuePtr rear; //队尾指针}LinkQueue;/* * 初始化队列 */Status InitQueue(LinkQueue *Q){ Q->front = Q->rear = (QueuePtr) malloc(sizeof(QNode)); if (!Q->front) { exit(OVERFLOW); } Q->front->next = NULL; return OK;}/* * 判断队列是否为空 */Status IsEmpty(LinkQueue Q){ if (Q.front->next == NULL) { return TRUE; } else { return FALSE; }}/* * 入队 */Status EnQueue(LinkQueue *Q, QElemType e){ QueuePtr p = (QueuePtr) malloc(sizeof(QNode)); if (!p) { exit(OVERFLOW); } p->data = e; p->next = NULL; Q->rear->next = p; Q->rear = p; return OK;}/* * 出队 */Status DeQueue(LinkQueue *Q, QElemType *e){ QueuePtr p; if (Q->front == Q->rear) { return ERROR; } p = Q->front->next; *e = p->data; Q->front->next = p->next; if (Q->rear == p) { Q->rear = Q->front; } free(p); return OK;}/* * 创建图 */Status CreateGraph(ALGraph *G){ int i, j, k; EdgeLink e; printf("请输入顶点数目和边数:\n"); scanf("%d%d", &G->vexNum, &G->edgeNum); getchar(); printf("请输入各顶点的数据:\n"); for (i = 0; i < G->vexNum; i++) { scanf("%c",&G->adjList[i].data); if (G->adjList[i].data == ' ') { i--; continue; } G->adjList[i].firstEdge = NULL; } printf("请依次输入边(Vi,Vj)的顶点序号:\n"); for (k = 0; k < G->edgeNum; k++) { scanf("%d%d", &i, &j); e = (EdgeLink) malloc(sizeof(EdgeNode)); e->adjvex = j; e->next = G->adjList[i].firstEdge; G->adjList[i].firstEdge = e; e = (EdgeLink) malloc(sizeof(EdgeNode)); e->adjvex = i; e->next = G->adjList[j].firstEdge; G->adjList[j].firstEdge = e; } return OK;}int visited[MAX_NUM]; //用于记录遍历状态/* * 递归从第i个结点深度优先遍历图 */void DFS(ALGraph G, int i){ EdgeLink p; visited[i] = TRUE; printf("%c ", G.adjList[i].data); p = G.adjList[i].firstEdge; while (p) { if (!visited[p->adjvex]) { DFS(G, p->adjvex); } p = p->next; }}/* * 深度优先遍历 */Status DFSTraverse(ALGraph G){ int i; for (i = 0; i < MAX_NUM; i++) { visited[i] = FALSE; } for (i = 0; i < G.vexNum; i++) { if (!visited[i]) { DFS(G, i); } } return OK;}/* * 广度优先遍历 */Status BFSTraverse(ALGraph G){ int i; EdgeLink p; LinkQueue Q; InitQueue(&Q); for (i = 0; i < MAX_NUM; i++) { visited[i] = FALSE; } for (i = 0; i < G.vexNum; i++) { if (!visited[i]) { visited[i] = TRUE; printf("%c ", G.adjList[i].data); EnQueue(&Q, i); while (!IsEmpty(Q)) { DeQueue(&Q, &i); p = G.adjList[i].firstEdge; while (p) { if (!visited[p->adjvex]) { visited[p->adjvex] = TRUE; printf("%c ", G.adjList[p->adjvex].data); EnQueue(&Q, p->adjvex); } p = p->next; } } } } return OK;}int main(){ ALGraph G; CreateGraph(&G); printf("深度优先遍历:"); DFSTraverse(G); printf("\n广度优先遍历:"); BFSTraverse(G); printf("\n");}
阅读全文
0 0
- 非线性结构——图
- 非线性结构——树
- [数据结构]非线性结构——多维数组
- 非线性数据结构——图
- 数据结构_非线性结构_图
- 非线性结构-多维数组
- 非线性结构之树
- OpenCV——非线性滤波器
- 线性结构与非线性结构
- 线性结构和非线性结构
- 线性结构和非线性结构
- 线性结构和非线性结构
- 线性结构和非线性结构
- 非线性结构之二叉树
- 广义表(非线性结构)
- 非线性数据结构——二叉树
- 非线性规划——qjzcy的博客
- 数值计算——求解非线性方程组
- php 获取服务器各项信息
- Largest Submatrix SPOJ
- 关于python装numpy这些
- HDU--OJ--找新朋友
- C++——创建类的时候用new与不用new 的区别(转)
- 非线性结构——图
- C++内存对齐
- centos安装python3
- 共享沙盒
- 7.30代码日记
- 基于Scrapy的爬虫爬取京东商品信息与评论
- POJ 3750 小孩报数问题(约瑟夫问题 水题 考验细节、编码能力)
- CNN卷积神经网络基础
- 《零基础入门学习Python》学习过程笔记【014字符串的使用】