这里是页首<手机端的用户对8住,我8会写适配>

数据结构-3

线性结构是树的一般情况,树则是的一般情况,那么现在开始实现图的有关算法

  先梳理一遍图的概述:

 


 

 

包含:Vertex一组顶点(非空)

   Edge一组边(可空)<集合V之间的关系的解释>  

 


 

定义图是由非空有限顶点集合(V)有限边集合(E)组合成的一种数据结构。Graph=( V, E )  V = {x | x ∈某个数据对象 } 是顶点的有穷非空集合;

 


 

术语无向图:顶点之间一定互通

   有向图:顶点之间存在单向连通

   邻接:俩点单/双向连通

   关联:一条边可以关联两个点

   完全图:任意两顶点互通

   :分为入度或出度,是对顶点的描述词,称该顶点的入度或出度,入度是只允许从别的点到该点,出度则是从该点到别的点

   :一般是边的长度,

   路径:依次遍历顶点序列之间的边所形成的轨迹。

   :循环的路径


 

存储结构

  邻接矩阵:二维数组,x轴坐标和y轴坐标处的值表示两点是否连通

  邻接表:在邻接矩阵出现大量空数据时,用链表代替非空值

  十字链表:顾名思义,交叉的链表构成的图,是邻接表的优化方案

  邻接多重表:十字链表在无向图上的优化方案

  边集数组:两个一维数组,一个储存V一个储存E,优点在于可以方便对边依次操作

 


 操作集

  创建图Graph Create

  插入顶点Graph InsertVertex

  插入边Graph Edge

  深度优先搜索DFS

  广度优先搜索BFS

  求最小生成树MST,(Prim算法和Kruskal算法)

  


 

我要实现的:

  以邻接矩阵和邻接表实现以上所有操作集...要耐心!!!

 


 

#include <iostream>
using namespace std;

struct Queue
{
    int arr[100];
    int maxlen;
    int left;//队列尾巴
    int right;//队列头
    int len;
    
    void Init()
    {
        maxlen = 100;
        left = 0;
        right = -1;
        len = 0;
    }
    bool IsNull()
    {
        if (len==0)return true;
        return false;
    }
    bool IsFull()
    {
        if (len == maxlen)return true;
        return false;
    }
    bool Enqueque(int num)
    {
        bool rt=false;
        if (!IsFull())//一定不能满
        {
            right++;
            arr[right%maxlen] = num;
            len++;
            rt = true;
        }
        return rt;
    }

    int Dequeque()
    {
        int rt = 0x7fffffff;
        if (!IsNull())//一定不能是空的
        {
            
            rt = arr[left % maxlen];
            len--;
            left++;
        }
        return rt;
    }
    void Show()
    {
        for (int i=0; i < len  ; i++)
        {
            cout<< arr[(left+i)%maxlen]<< " ";
        }
        cout << endl;
    }
};
struct Path
{
    int* parr;
    int len;
    int* pre;

    void Init(int l)
    {
        parr = (int*)malloc(sizeof(int) * l);
        pre = (int*)malloc(sizeof(int) * l);//用于BFS记录路径,但是最好采用结构体!
        len = 0;
    }
    void Add(int _pre,int now)
    {
        parr[len] = now;
        pre[len++] = _pre;
    }
    int Find(int value)
    {
        int r = -1;
        for (int i = 0; i < len; i++)
        {
            if (parr[i] == value)
            {
                r = i; break;
            }
        }
        return r;
    }
    bool Contain(int a)
    {
        for (int i = 0; i < len; i++)
        {
            if (a == parr[i])return true;
        }
        return false;
    }

    void Show(int type)
    {
        if (type == 0)
        {
            for (int i = 0; i < len; i++)
            {
                cout << parr[i] << " ,";
            }
        }
        else
        {
            for (int i = len-1; i >=0; i--)
            {
                cout << parr[i] << " ,";
            }
        }
    }
};
Path rPath;
struct Graph
{
    int** arr;
    int h;
    int w;

    void Create(int _h)
    {
        arr = (int**)malloc(sizeof(int*) *_h);
        for (int i = 0; i < _h; i++)
        {
            arr[i]= (int*)malloc(sizeof(int) * _h);
        }
        h = _h;
        w = _h;
        for(int j=0;j<_h;j++)
        for (int i = 0; i < _h; i++)
        {
            arr[j][i] = 0;
        }
    }
    //由于邻接矩阵点已经全部存在,所以只需要设置边即可 
    void SetEdge(int _h,int _w,int value)
    {
        arr[_h][_w] = value;
    }
    void DFS(Path p, Graph map, int now, int target, int size, int len)//size为整张图的尺寸
    {
        if (now == target)
        {
            cout << "DFS ";
            p.Show(0);
            cout << endl;
            if (len<rPath.len)
            {
                rPath = p;
            }
            return;
        }
        len++;
        p.Add(-1,now);
        for (int i = 0; i < size; i++)
        {
            if (w = map.arr[now][i] != 0 && !p.Contain(i))//与1相邻的点是否包含在path中
            DFS(p,map, i, target, size,len);
            //C语言结构体参数为值传递,故不需要回溯,如果使用数组,就必须回溯
        }

    }
    Path BFS(Graph map, int now, int target,int size)
    {
        //层序遍历一样的方法
        
        Path p;//用于存放已经走过的点
        p.Init(100);

        Path rp;//用于存放路径
        rp.Init(100);

        Queue q;
        q.Init();
        q.Enqueque(now);
        p.Add(-1,now);
        int pi = 0;
        while (!q.IsNull())
        {
            int t = q.Dequeque();//取出一个
            for (int i = 0; i < size; i++)
            {
                if (map.arr[t][i] != 0)
                {
                    if (i == target)
                    {
                        p.Add(t, i);
                        cout << "BFS";
                        while (i != -1)
                        {
                            rp.Add(t, i);
                            i = p.pre[p.Find(i)];
                        }
                        return rp;
                    }
                    if (!p.Contain(i))//未走过
                    {
                        q.Enqueque(i);
                        p.Add(t,i);
                    }
                }
            }
        }
        cout << "找不到路径"<<endl;
        return rp;
    }

    void Show()
    {
        for (int j = 0; j < h; j++)
        {
            for (int i = 0; i < w; i++)
            {
                cout << arr[j][i] << " ";
            }
            cout<<endl;
        }
    }
};

void AA(Path p)
{
    cout << "函数内 设置前 p.parr[0] = " << p.parr[0] << endl;
    p.parr[0] = 2;
    cout << "函数内 设置后 p.parr[0] = " << p.parr[0] << endl;
}

int main()
{
    
    Graph t;
    t.Create(6);//六个点


    t.SetEdge(0, 1, 1);
    t.SetEdge(1, 0, 1);

    t.SetEdge(0, 5, 1);
    t.SetEdge(5, 0, 1);

    t.SetEdge(1, 2, 1);//设置1->2距离1
    t.SetEdge(2, 1, 1);//设置2->1距离1

    t.SetEdge(2, 3, 1);
    t.SetEdge(3, 2, 1);

    t.SetEdge(2, 4, 1);
    t.SetEdge(4, 2, 1);

    t.SetEdge(3, 4, 1);
    t.SetEdge(4, 3, 1);

    t.SetEdge(4, 5, 1);
    t.SetEdge(5, 4, 1);

    t.SetEdge(3, 5, 1);
    t.SetEdge(5, 3, 1);


    t.Show();
    cout << endl;
    //遍历

    Path p;
    p.Init(100);
    
    rPath.Init(100);
    rPath.len = 99999;
    t.DFS(p,t,1,4,6,0);
    cout << "DFS最短路径:"; rPath.Show(0); cout << "4 ,"; cout << endl;
    cout << endl;

    rPath = t.BFS(t, 1, 4, 6);

    cout << "最短路径:"; rPath.Show(1); cout << endl;
    cout << endl;
    return 0;

}

未完待续

  

     

posted @ 2019-08-01 21:27  comeonlilith  阅读(197)  评论(0)    收藏  举报
这里是页脚