数据结构(图的存储结构)

树形结构节点之间是一对多的关系,节点之间有明显的分支关系和层次关系。每一层的结点可以和下一层的多个节点相关,但只能和上一层的一个节点相关。而图中的顶点间的关系是任意的,没有明显的层次关系。
图的定义:图是由非空顶点集合和描述顶点间的关系–边或弧的集合组成。
图的基本术语
边,弧,弧头,弧尾:无向图之间顶点的连线称为边。有向图之间定点的连线称为弧。弧的始点称为弧尾,弧的终点称为弧尾
无向完全图:任意两个顶点之间都有边相连(n(n-1)/2条边)
有向完全图:任意两个顶点之间都有弧相连(n(n-1)条边)
顶点的度,入度,出度:无向图中,顶点v的度是指依附于顶点v的边数;有向图中,顶点v的度是指入度(v为弧头)和出度(v为弧尾)之和
权,网:边上所附带的数据信息称为权,边上带权的图称为网,或者网络
简单路径,简单回路:一条路径上顶点不重复出现称为简单路径。除第一个顶点和最后一个定点重复外,其他定点不重复的回路称为简单回路
连通,(强)连通图:两个顶点之间有路径,称这两个顶点之间是连通的。任意两个丁点都联通的图称为连通图。
(强)连通分量,生成树:图的极大连通图称为连通分量,图的包含全部顶点的极小连通图称为生成树
(n-1条边)
图的存储结构
图的接口定义

 interface IGraph<T>
    {
        /// <summary>
        /// 获取顶点的数目
        /// </summary>
        /// <returns></returns>
        int GetNumOfVertex();
        /// <summary>
        /// 获取边的数目
        /// </summary>
        /// <returns></returns>
        int GetNumOfEdge();
        /// <summary>
        /// 两个顶点之间设置边
        /// </summary>
        /// <param name="v1"></param>
        /// <param name="v2"></param>
        void SetEdge(Node<T> v1,Node<T> v2);
        /// <summary>
        /// 两个定点之间删除边
        /// </summary>
        /// <param name="v1"></param>
        /// <param name="v2"></param>
        void DelEdge(Node<T> v1,Node<T> v2);
        /// <summary>
        /// 判断两个顶点之间是否有边
        /// </summary>
        /// <param name="v1"></param>
        /// <param name="v2"></param>
        /// <returns></returns>
        bool IsEdge(Node<T> v1,Node<T> v2);
    }

顶点类

class Node<T>
    {
        private T data;

        public Node(T val)
        {
            data = val;
        }
        public T Data { get { return data; }set { data = value; } }
    }

邻接矩阵
用一个一维数组用来存储顶点信息。一个二维数组用来存储边(或弧)的信息
邻接矩阵类

class GraphAdjMatrix<T>:IGraph<T>
    {
        //边稀疏的情况下,邻接矩阵比邻接表更节省空间
        public Node<T> [] nodes;//顶点信息
        private int numEdges;//边(或弧)得数目
        private int[,] matrix;//边(或弧)的信息

        public GraphAdjMatrix(int n)
        {
            nodes = new Node<T>[n];
            numEdges = n;
            matrix=new int[n,n];
        }

        public Node<T> GetNode(int index)
        {
            return nodes[index];
        }

        public void SetNode(int index,Node<T> val)
        {
            nodes[index] = val;
        }
        public int NumEdges { get { return numEdges; } set { numEdges = value; } }

        public int GetMatrix(int index1,int index2)
        {
            return matrix[index1, index2];
        }

        public void SetMatrix(int index1,int index2)
        {
            matrix[index1, index2] = 1;//无向图
        }

        public int GetIndex(Node<T> v )
        {
            for (int i = 0; i < nodes.Length; i++)
            {
                if (nodes[i].Equals(v))
                {
                    return i;
                }
            }
            return -1;
        }

        public int GetNumOfVertex()
        {
            return nodes.Length;
        }

        public int GetNumOfEdge()
        {
            return numEdges;
        }

        public void SetEdge(Node<T> v1, Node<T> v2)
        {
            matrix[GetIndex(v1), GetIndex(v2)] = 1;
            matrix[GetIndex(v2), GetIndex(v1)] = 1;
            numEdges++;
        }

        public void DelEdge(Node<T> v1, Node<T> v2)
        {
            matrix[GetIndex(v1), GetIndex(v2)] = 0;
            matrix[GetIndex(v2), GetIndex(v1)] = 0;
            numEdges--;
        }

        public bool IsEdge(Node<T> v1, Node<T> v2)
        {
            return matrix[GetIndex(v1), GetIndex(v2)] == 1;
        }
    }

邻接表
是一种顺序存储和链式存储相结合的存储结构,类似于树的孩子链表表示法。顺序存储指的是把顶点信息用一个数组存储起来,而链式存储指的是把与之相连接的顶点用链表连接起来。
顶点信息类

  class VexNode<T>
    {
        private Node<T> data;
        private AdjListNode<T> firstAdj;
        public Node<T> Data { get { return data; } set { data = value; } }
        public AdjListNode<T> FirstAdj { get { return firstAdj; } set { firstAdj = value; } }

        public VexNode()
        {
            data = null;
            firstAdj = null;
        }
        public VexNode(Node<T> nd)
        {
            data = nd;
            firstAdj = null;
        }

        public VexNode(Node<T> nd, AdjListNode<T> fir)
        {
            data = nd;
            firstAdj = fir;
        }
    }

与顶点相连的结点类

   class AdjListNode<T>
    {
        private int adjvex;
        private AdjListNode<T> next;
        public int Adjvex { get { return adjvex; } set { adjvex = value; } }
        public AdjListNode<T> Next { get { return next; } set { next = value; } }

        public AdjListNode(int vex)
        {
            adjvex = vex;
            next = null;
        } 
    }

连接表类

 class GraphAdjList<T>:IGraph<T>
    {
        private VexNode<T>[] adjList;
        public VexNode<T> this[int index] { get { return adjList[index]; }set { adjList[index] = value; } }

        public GraphAdjList(Node<T> []nodes )
        {
            adjList=new VexNode<T>[nodes.Length];
            for (int i = 0; i < adjList.Length; i++)
            {
                adjList[i].Data = nodes[i];
                adjList[i].FirstAdj = null;
            }
        }

        public int GetIndex(Node<T> v )
        {
            for (int i = 0; i < adjList.Length; i++)
            {
                if (adjList[i].Equals(v))
                {
                    return i;
                }
            }
            return -1;
        }
        public int GetNumOfVertex()
        {
            return adjList.Length;
        }

        public int GetNumOfEdge()
        {
            int count = 0;
            foreach (VexNode<T> temp in adjList)
            {
                AdjListNode<T> p = temp.FirstAdj;
                while (p != null)
                {
                    p = p.Next;
                    count++;
                }
            }
            return count / 2;
        }

        public void SetEdge(Node<T> v1, Node<T> v2)
        {
            AdjListNode<T> p = new AdjListNode<T>(GetIndex(v2));
            if (adjList[GetIndex(v1)].FirstAdj == null)
            {
                adjList[GetIndex(v1)].FirstAdj = p;
            }
            else
            {
                p.Next = adjList[GetIndex(v1)].FirstAdj;
                adjList[GetIndex(v1)].FirstAdj = p;
            }
            p=new AdjListNode<T>(GetIndex(v1));
            if (adjList[GetIndex(v2)].FirstAdj == null)
            {
                adjList[GetIndex(v2)].FirstAdj = p;
            }
            else
            {
                p.Next = adjList[GetIndex(v2)].FirstAdj;
                adjList[GetIndex(v2)].FirstAdj = p;
            }
        }

        public void DelEdge(Node<T> v1, Node<T> v2)
        {
            AdjListNode<T> p = adjList[GetIndex(v1)].FirstAdj;
            AdjListNode<T> pre = null;
            while (p!=null)
            {
                if (p.Adjvex==GetIndex(v2))
                {
                    break;
                }
                pre = p;
                p = p.Next;
            }
            pre.Next = p.Next;
            p = adjList[GetIndex(v2)].FirstAdj;
            pre = null;
            while (p!=null)
            {
                if (p.Adjvex==GetIndex(v1))
                {
                    break;
                }
                pre = p;
                p = p.Next;
            }
            pre.Next = p.Next;
        }

        public bool IsEdge(Node<T> v1, Node<T> v2)
        {
            AdjListNode<T> p = adjList[GetIndex(v1)].FirstAdj;
            while (p!=null)
            {
                if (p.Adjvex==GetIndex(v2))
                {
                    return true;
                }
                p = p.Next;
            }
            return false;
        }
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值