6.2.3+6.2.4十字链表、邻接多重表
知识总览:
邻接矩阵缺点是空间复杂度高,邻接表缺点是在找有向图的入度时时间消耗太大(要遍历所有节点)
十字链表只用于存储有向图:
十字链表存储图的话定义2个结构体:节点+弧,从某个顶点绿色的指针线一直往后找绿色的话可以找到从当前顶点往外发射的所有弧/边(该顶点出度),顺着橙色的指针一直往后找橙色可以找到所有指向该顶点的弧(该顶点入度,即解决了邻接表找有向图入度难的问题),不管是从绿色还是从橙色开始找,最后都没有边节点的时候就记为null
过程如下:
下图中的A、B、C、D四个顶点数据信息存储在一维数组里,即每个顶点都有索引编号,即A编号为0,B为1,C为2,D为3,从下图中可看出从A节点出发的边有2条,A->B,A->C,指向A节点的边有2条,D->A,C->A,
如找A节点的出度:从A节点firstout作为弧尾绿色块发出的指针指向出发(A对应的0号节点块为绿色色以下一直找绿色块发出的线),可以看到指向0和1块,即0编号节点指向1编号节点,即对应的A节点指向B节点,再从0和1块下方所在的绿色块发出的线出发指向0和2块,即0编号节点指向2编号节点,即对应的A节点指向C节点,继续从当前0和2块下方的绿色块发出的线出发,发现当前的绿色块有^标识,即再无边节点指向了,再无节点和A节点相邻了,到此结束
找A节点的入度:从A节点firstin作为弧头的橙色指针指向出发(A对应的0号节点块为橙色以下一直找橙色块发出的线),可以看到指向了2和0块,即2编号节点指向0编号节点,即对应的C节点指向A节点,再从2和0块所在的橙色块发出的线出发指向了3和0块,即3编号节点指向0编号节点,即对应的D节点指向A节点,继续从当前3和0块的橙色块发出的线出发,发现当前的橙色块有^标识,即再无边节点指向了,即再无节点和A节点相邻了,到此结束
邻接表/邻接矩阵存储无向图缺点:
邻接矩阵存储无向图缺点主要是空间复杂度高
邻接表存储无向图缺点主要是时间复杂度高,因为一条边对应2份边节点冗余信息,比如要删除A到B这条边,需要同时删除A节点0号节点的边节点中1号边节点和B节点1号边节点的边节点信息中的0号边节点,如果要删除A节点,则需要删除A节点0号节点所有信息+所有节点的边节点中有A节点的(即所有指向A节点的路径中的边节点,包括B、C、D节点),即时间复杂度高
邻接多重表只用于存储无向图:
邻接多重表图的话定义2个结构体:节点信息+边
过程如下:
和十字链表类似,对于A节点来说,有B和D节点和A直接相邻。从A节点firstEdge指针指向出发,可以看到指向了0和1块,即0编号节点指向1编号节点(因为是无向图,也可以说是1指向0,这俩等价),即对应的A节点指向B节点,因为A节点所对应的0号节点是橙色块,所以再从0和1块所在的橙色块发出的线出发指向了0和3块,即0编号节点指向3编号节点(也可以说是3指向0,这俩等价),即对应的A节点指向D节点,继续从当前0和3块的橙色块发出的线出发,发现当前的橙色块有^标识,即再无节点和A节点相邻了,到此结束
对于B节点来说,有A、C、E节点和B直接相邻。从B节点firstEdge指针指向出发,可以看到指向了0和1块,即0编号节点指向1编号节点(因为是无向图,也可以说是1指向0,这俩等价),即对应的A节点指向B节点,因为B节点所对应的1号节点是绿色块,所以再从0和1块所在的绿色块发出的线出发指向了2和1块,即2编号节点指向1编号节点(因为是无向图,也可以说是1指向2,这俩等价),即对应的C节点指向B节点,继续从当前2和1块的绿色块发出的线出发找到4和1块,即4编号节点指向1编号节点(因为是无向图,也可以说是1指向4,这俩等价),即对应的E节点指向B节点,继续从当前4和1块的绿色块发出的线出发,发现当前的绿色块有^标识,即再无节点和B节点相邻了,到此结束
优点:一条无向的路径对应的边节点信息在整个邻接多重表中只对应了一份,
删除一条边的时候,把该边节点信息删除了之后,需要对应有关连接到该边节点的指针都修改指向下一条位置。如AB边删了之后,需要A节点把firstEdge指针指向曾经橙色块指向的下一个位置(即和A节点相邻的下一个边节点),需要B节点把firstEdge指针指向绿色块指向的下一个位置(即和B节点相邻的下一个边节点)
删除一个顶点:
如删除E顶点,该顶点下的firstEdge指针下指向的边节点信息都需删除,其他指向这些边节点的指针也需要更改指向
知识回顾:
以上纯属个人理解。。。。。。。