动手实现 数据结构 之 “十字链表”
来源:互联网 发布:手机喊麦用什么软件 编辑:程序博客网 时间:2024/05/01 20:15
与邻接链表图非常相似,相对而言多了前向边的处理
使用 C语言 十字链表 实现了: 添加边,删除边,查找边的功能
#include <stdio.h>#include <stdlib.h>typedef int bool;#define false 0;#define true 1;typedef struct Edge { double weight; int source; int dest; struct Edge * linkPre; struct Edge * linkNex;} Edge;typedef struct CrossListMap { int n; int * data; struct Edge ** headPre; struct Edge ** headNex;} CrossListMap;void InitMap(struct CrossListMap * map, int n);void DestroyMap(struct CrossListMap * map);struct Edge * AddEdge(struct CrossListMap * map, unsigned int source/*0~n-1*/, unsigned int dest/*0~n-1*/, double weight);bool RemoveEdge(struct CrossListMap * map, unsigned int source/*0~n-1*/, unsigned int dest/*0~n-1*/);struct Edge * GetEdge(struct CrossListMap * map, unsigned int source/*0~n-1*/, unsigned int dest/*0~n-1*/);void print1(struct CrossListMap * map);void print2(struct CrossListMap * map);// 初始化有 n 个节点的图void InitMap(struct CrossListMap * map, int n) { map->n = n; map->data = (int*)malloc(n*sizeof(int)); map->headPre = (struct Edge**)malloc(n*sizeof(struct Edge*)); map->headNex = (struct Edge**)malloc(n*sizeof(struct Edge*)); for(int i=0; i<n; i++) { map->headPre[i] = NULL; map->headNex[i] = NULL; }}void DestroyMap(struct CrossListMap * map) { free(map->data); for(int i=0; i<map->n; i++) { struct Edge* nex; for (struct Edge* e=map->headNex[i]; e!=NULL; e=nex) { nex = e->linkNex; free(e); } } free(map->headPre); free(map->headNex);}struct Edge * AddEdge(struct CrossListMap * map, unsigned int source/*0~n-1*/, unsigned int dest/*0~n-1*/, double weight){ if(map->n < source || map->n < dest || map == NULL) return NULL; struct Edge * edge = (struct Edge *)malloc(sizeof(struct Edge)); edge->weight = weight; edge->source = source; edge->dest = dest; //-------------部分一 后向边的处理------------- struct Edge * nex1 = map->headNex[source]; struct Edge * nex2 = nex1; // 查找插入位置 while (nex2 != NULL) { if(dest < nex2->dest) break; else if(dest == nex1->dest) return NULL; nex1 = nex2; nex2 = nex2->linkNex; } // 插入新的边为第一条边 if (nex1 == NULL || dest < nex1->dest) { map->headNex[source] = edge; } else { nex1->linkNex = edge; } edge->linkNex = nex2; //-------------部分二 前向边的处理------------- struct Edge * pre1 = map->headPre[dest]; struct Edge * pre2 = pre1; // 查找插入位置 while (pre2 != NULL) { if(source < pre2->source) break; else if(source == pre1->source) return NULL; pre1 = pre2; pre2 = pre2->linkPre; } // 插入新的边为第一条边 if (pre1 == NULL || source < pre1->source) { map->headPre[dest] = edge; } else { pre1->linkPre = edge; } edge->linkPre = pre2; return edge;}bool RemoveEdge(struct CrossListMap * map, unsigned int source/*0~n-1*/, unsigned int dest/*0~n-1*/) { if(map->n < source || map->n < dest || map == NULL) return false; //-------------部分一 后向边的处理------------- struct Edge * nex1 = map->headNex[source]; struct Edge * nex2 = nex1; while(nex2 != NULL && nex2->dest < dest && nex2->linkNex != NULL) { nex1 = nex2; nex2 = nex2->linkNex; } if(nex2 == NULL || nex2->dest != dest) return false; if(nex1 == nex2) { map->headNex[source] = nex2->linkNex; } else { nex1->linkNex = nex2->linkNex; } //-------------部分二 前向边的处理------------- struct Edge * pre1 = map->headPre[dest]; struct Edge * pre2 = pre1; while(pre2 != NULL && pre2->source < source && pre2->linkPre != NULL) { pre1 = pre2; pre2 = pre2->linkPre; } if(pre2 == NULL || pre2->source != source) return false; if(pre1 == pre2) { map->headPre[dest] = pre2->linkPre; } else { pre1->linkPre = pre2->linkPre; } free(nex2); return true;}struct Edge * GetEdge(struct CrossListMap * map, unsigned int source/*0~n-1*/, unsigned int dest/*0~n-1*/){ if(map->n < source || map->n < dest || map == NULL) return NULL; struct Edge * edge = map->headNex[source]; while(edge != NULL && edge->dest < dest && edge->linkNex != NULL) { edge = edge->linkNex; } if(edge == NULL || edge->dest != dest) return NULL; // 不存在从 source 到 dest 这条边 return edge;}void print(struct CrossListMap * map) { for (int i=0; i<map->n; i++) for (struct Edge * e=map->headNex[i]; e!=NULL; e=e->linkNex) printf("from: %d to: %d, weight: %.1lf\n", e->source, e->dest, e->weight);}void print2(struct CrossListMap * map) { for (int i=0; i<map->n; i++) for (struct Edge * e=map->headPre[i]; e!=NULL; e=e->linkPre) printf("%d comes from: %d, weight: %.1lf\n", e->dest, e->source, e->weight);}int main(void){ CrossListMap map; InitMap(&map, 4); // 图,起点,终点,权值 AddEdge(&map, 0, 1, 3.0); AddEdge(&map, 0, 2, 3.0); AddEdge(&map, 2, 0, 4.0); AddEdge(&map, 2, 3, 4.0); AddEdge(&map, 3, 0, 5.0); AddEdge(&map, 3, 1, 5.0); AddEdge(&map, 3, 2, 5.0); RemoveEdge(&map, 0, 1); print(&map); print2(&map); struct Edge * searchEdge = GetEdge(&map, 0, 1); if(searchEdge != NULL) printf("Weight of edge 0 to 2 is %.1lf\n", searchEdge->weight); DestroyMap(&map); return 0;}
0 0
- 动手实现 数据结构 之 “十字链表”
- 动手实现 数据结构 之 “单向链表”
- 动手实现 数据结构 之 “双向链表”
- 动手实现 数据结构 之 “跳跃链表”
- 数据结构之十字链表
- 数据结构之图的十字链表
- 动手实现 数据结构 之 “栈”
- 动手实现 数据结构 之 “堆”
- 动手实现 数据结构 之 “队列”
- 数据结构之---C/C++实现稀疏矩阵的十字链表
- 数据结构之---C++语言实现图的十字链表存储表示
- 数据结构之---C语言实现图的十字链表存储表示
- 数据结构-图-十字链表
- 数据结构:图(十字链表存储 c++实现)
- 学习笔记------数据结构(C语言版)数组之十字链表
- 动手实现 数据结构 之 “邻接链表图”
- 动手实现 数据结构 之 “二叉树”
- 动手实现 数据结构 之 “AVL树”
- poj1861Network(最小生成树-克鲁斯卡尔算法)
- 用户态内核态通信 (一)
- NVMe设备命令大小限制
- 简单的传球游戏(矩阵)
- 对于校庆网站开发及上线的思考
- 动手实现 数据结构 之 “十字链表”
- MongoDB HTTP Interfaces
- ubuntu下搭建tftp服务器
- jkgjgkgj后方可看见个更健康急功近利
- 设计模式(1)——抽象工厂模式
- Github连击200天(1)——ShowCase
- 子窗体在父窗体中的展开方式
- 用户态内核态通信(二)
- Swift学习:2.整型于浮点数