数据结构学习

    技术2022-05-11  87

           图算是一种较复杂的数据结构了。图由 边的集合与顶点的集合 组成。关于图有许多种存储方式。在这一篇中,在深度优先搜索(DFS)和广度优先搜索(BFS)算法中,树用邻接表的方式存储。在最小生成树的Prim算法中,树用的时邻接矩阵的方式表示。

    下面对Prim算法做一个简单的介绍。

            Prim算法以点集合逐步扩展的方式选择连接它们的最小的边。

    先指定一个点加入空集中,然后把连接它的最小边的另一个顶点加入集合中,在重复前一个步骤,逐步扩大直到所有的点都加入到了集合中。

    #include  < iostream > #include  < queue > #include  < string > using   namespace  std; ////error class // class BadOccur // { // public:     //     BadOccur(const string szErrorDescription) //     { //         m_szErrorDescription = szErrorDescription; //     } //     void BadOccurPrint() //     { //         cout << m_szErrorDescription << endl; //     } // private: //     string m_szErrorDescription; // }; // structure of the adjacent vertex nodes typedef  struct  TAdjVertexNode {    int nAdjVertexNum; //sequence number of the adjacent vertex node    struct TAdjVertexNode* pNextAdjVertex; //pointer of the next adjacent vertex node} TAdjVertexNode; // structure of the vertex nodes typedef  struct  TVertexNode {    int nVertexNum; //sequence number of the vertex node    struct TAdjVertexNode* pFirstAdjVertex; //pointer of the vertex's first adjacent node } TVertexNode;TVertexNode *  CreatGraph( int  NodesNum) {    TVertexNode* pVertexArray = new TVertexNode [NodesNum + 1];    for (int i = 1; i <= NodesNum; i++)    {        pVertexArray[i].nVertexNum = i;        int nAmount = 0;        cout << "Please give the number of adjacent nodes of the " << i << " th node" << endl;        cin >> nAmount;        if (0 == nAmount)        {            pVertexArray[i].pFirstAdjVertex = NULL;        }        else        {            TAdjVertexNode* pPreNode = NULL;            for (int j = 1; j <= nAmount; j++)            {                TAdjVertexNode* pNewNode = new TAdjVertexNode;                cout << "Please enter the sequence number of the node." << endl;                int nSequenceNum = 0;                cin >> nSequenceNum;                pNewNode->nAdjVertexNum = nSequenceNum;                if (1 == j)                {                    pVertexArray[i].pFirstAdjVertex = pNewNode;                }                else                {                    pPreNode->pNextAdjVertex = pNewNode;                }                pPreNode = pNewNode;                pNewNode->pNextAdjVertex = NULL;            }        }    }    return pVertexArray;} typedef  void  ( * TraverseMethod) (TVertexNode * int int * ); /**    Function Name             :BFS*    function                           :broad traverse the graph from one vertex*    detail                               :none*    author                             :weixiong*    time                                 :2007-2-1*    return type                      :void*   return description  : *    function parameters    :TVertexNode* pVertexesArray    the storage array of the graph *                                                 int nVertexSequenceNum         sequence number of current vertex*                                                 int* pVertexesFlagArray        the flag array of all the vertexes*/ void  BFS(TVertexNode *  pVertexesArray,  int  nVertexSequenceNum,  int *  pVertexesFlagArray) {    queue<int> qAdjacentNodes;    TAdjVertexNode* pCurrentNode = NULL;    int nCurrentNodeNum = nVertexSequenceNum;    cout << nCurrentNodeNum << " ";    pVertexesFlagArray[nCurrentNodeNum] = 1;    for (pCurrentNode = pVertexesArray[nCurrentNodeNum].pFirstAdjVertex; NULL != pCurrentNode; pCurrentNode = pCurrentNode->pNextAdjVertex)    {        nCurrentNodeNum = pCurrentNode->nAdjVertexNum;        cout << nCurrentNodeNum << " ";        pVertexesFlagArray[nCurrentNodeNum] = 1;        qAdjacentNodes.push(nCurrentNodeNum);    }    while (!qAdjacentNodes.empty())    {        pCurrentNode = pVertexesArray[nCurrentNodeNum].pFirstAdjVertex;        if (pCurrentNode)        {            nCurrentNodeNum = pCurrentNode->nAdjVertexNum;        }        for (; NULL != pCurrentNode; pCurrentNode = pCurrentNode->pNextAdjVertex)        {            nCurrentNodeNum = pCurrentNode->nAdjVertexNum;            if (0 == pVertexesFlagArray[nCurrentNodeNum])            {                cout << nCurrentNodeNum << " ";                pVertexesFlagArray[nCurrentNodeNum] = 1;                qAdjacentNodes.push(nCurrentNodeNum);            }        }        nCurrentNodeNum = qAdjacentNodes.front();        qAdjacentNodes.pop();    }} /**    Function Name        :DFS*    function            :depth traverse the graph from one vertex*    detail                :none*    author                :weixiong*    time                :2007-2-1*    return type            :void*   return description  : *    function parameters    :TVertexNode* pVertexesArray    the storage array of the graph *                         int nVertexSequenceNum         sequence number of current vertex*                          int* pVertexesFlagArray        the flag array of all the vertexes*/ void  DFS(TVertexNode *  pVertexesArray,  int  nVertexSequenceNum,  int *  pVertexesFlagArray) {    cout << pVertexesArray[nVertexSequenceNum].nVertexNum << " ";    pVertexesFlagArray[nVertexSequenceNum] = 1;    TAdjVertexNode* pCurrentVertex = pVertexesArray[nVertexSequenceNum].pFirstAdjVertex;    int nCurrentVertexNum = 0;    if (NULL != pCurrentVertex)    {        nCurrentVertexNum = pCurrentVertex->nAdjVertexNum;    }    for (; NULL != pCurrentVertex; pCurrentVertex = pCurrentVertex->pNextAdjVertex)    {        if (0 == pVertexesFlagArray[nCurrentVertexNum])        {            DFS(pVertexesArray, nCurrentVertexNum, pVertexesFlagArray);        }    }} /**    Function Name        :DepthFirstTraveralGraph*    function            :traverse graph using the depth first order*    detail                :none*    author                :weixiong*    time                :2007-2-1*    return type            :bool*   return description  : true                                      two matrices has multiplied*                         false                                     two matrices can't be multiplied*    function parameters    :int nNodesNum                             number of all the vertexes*                         int* pVertexesFlagArray                   the flag array of all the vertexes*                          TVertexNode* pVertexesArray               the storage array of the vertex*/ void  DepthFirstTraveralGraph( int  nNodesNum,  int *  pVertexesFlagArray, TVertexNode *  pVertexesArray) {    int nVertex = 1;    TraverseMethod p = NULL;    cout << "Please choose your traversal method: 1. BFS   2. DFS" << endl;    int nChoice = 0;    cin >> nChoice;    while(nVertex != nNodesNum)    {        int nCurrentVertex = pVertexesArray[nVertex].nVertexNum;        if (0 == pVertexesFlagArray[nVertex])        {            switch (nChoice)            {            case 1:                    BFS(pVertexesArray, nVertex, pVertexesFlagArray);                    break;            case 2:                    DFS(pVertexesArray, nVertex, pVertexesFlagArray);                    break;            default:                    cout << "Bad choice!" << endl;            }        }        nVertex++;    }} const   int  MAX  =   100 ; // If it hasn't directly path from Vi to Vj, we denote value(Vi, Vj) = 100  const   int  VERNUM  =   6 ; /*    Function Name        :MiniSpanTree_Prim*    function            :creat the minimal span tree*    detail                :none*    author                :weixiong*    time                :2007-2-1*    return type            :void*   return description  :  *    function parameters    :int ppGraphMatrix[][VERNUM]      the storage of the orginal tree     *                                                int nVertexNum                               the vertexes number it has     */ void  MiniSpanTree_Prim( int  ppGraphMatrix[][VERNUM],  int  nVertexNum) {    ppGraphMatrix[0][0= 1;    int nRow = 0;//record row of the minimal edge    int nCol = 0;    for (int k = 0; k < nVertexNum - 1; k++)    {        int nMinEdge = MAX;//record the minimal value        for (int i = 0; i < nVertexNum; i++)        {            if (1 == ppGraphMatrix[i][i])            {                for (int j = 0; j < nVertexNum; j++)                {                    if ((0 == ppGraphMatrix[j][j]) && (ppGraphMatrix[i][j] < nMinEdge))                    {                        nMinEdge = ppGraphMatrix[i][j];                        nRow = i;                        nCol = j;                    }                }            }        }        ppGraphMatrix[nCol][nCol] = 1;        if (nRow > nCol)            ppGraphMatrix[nRow][nCol] = -ppGraphMatrix[nRow][nCol];        else            ppGraphMatrix[nCol][nRow] = -ppGraphMatrix[nCol][nRow];    }} void  PrintGraph( int  ppGraphMatrix[][VERNUM]) {         for (int i = 0; i < VERNUM; i++)        {            for (int j = 0; j < VERNUM; j++)            {                cout << ppGraphMatrix[i][j] << ' ';            }            cout << endl;        }} typedef struct TEdge{ int nVertexBegin; int nVertexEnd; int nVertexValue; int nFlag;}TEdge; /*    Function Name        :MiniSpanTree_Prim*    function            :creat the minimal span tree*    detail                :none*    author                :weixiong*    time                :2007-2-1*    return type            :void*   return description  :  *    function parameters    :TEdge GraphEdgeArray[],      the storage of the edges of the tree     *                                                TAdjVertexNode GraphVertexArray[] the storage of the vertexes array     */ void MiniSpanTree_Kruskal(TEdge GraphEdgeArray[], TAdjVertexNode GraphVertexArray[]){ int nChosenEdges = 1; while (nChosenEdges < VERNUM) {  int nMin = MAX;  int nEdge = 0;  int nEdgeBegin = 0;  int nEdgeEnd = 0;  for (int i = 1; i <= EDGENUM; i++) //search the minimal edge from the edges which were not chosen   {   if ((0 == GraphEdgeArray[i].nFlag) && (GraphEdgeArray[i].nVertexValue < nMin))   {    nMin = GraphEdgeArray[i].nVertexValue;    nEdge = i;    nEdgeBegin = GraphEdgeArray[i].nVertexBegin;    nEdgeEnd = GraphEdgeArray[i].nVertexEnd;   }  }   //add the chosen edge's initial vertex to its terminal vertex's list  TAdjVertexNode* pCurrentVertex = &GraphVertexArray[nEdgeBegin];  for (; (pCurrentVertex->pNextAdjVertex != NULL) && (pCurrentVertex->nAdjVertexNum != nEdgeEnd); pCurrentVertex = pCurrentVertex->pNextAdjVertex)  {}  if (NULL == pCurrentVertex->pNextAdjVertex)  {   TAdjVertexNode* pNewVertex = new TAdjVertexNode;   pNewVertex->nAdjVertexNum = nEdgeEnd;   pNewVertex->pNextAdjVertex = NULL;   pCurrentVertex->pNextAdjVertex = pNewVertex;  }   //add the chosen edge's terminal vertex to its initial vertex's list  pCurrentVertex = &GraphVertexArray[nEdgeEnd];  for (; (pCurrentVertex->pNextAdjVertex != NULL) && (pCurrentVertex->nAdjVertexNum != nEdgeBegin); pCurrentVertex = pCurrentVertex->pNextAdjVertex)  {}  if (NULL == pCurrentVertex->pNextAdjVertex)  {   TAdjVertexNode* pNewVertex = new TAdjVertexNode;   pNewVertex->nAdjVertexNum = nEdgeBegin;   pNewVertex->pNextAdjVertex = NULL;   pCurrentVertex->pNextAdjVertex = pNewVertex;   GraphEdgeArray[nEdge].nFlag = 1;   nChosenEdges++;  }  }} int  main() {    //MiniSpanTree    static int ppGraphMatrix[][VERNUM] =    {        {0  ,6  ,1,5  ,MAX,MAX},        {6  ,0  ,5,MAX,3  ,MAX},        {1  ,5  ,0,5  ,6  ,4},        {5  ,MAX,5,0  ,MAX,2},        {MAX,3  ,6,MAX,0  ,6},        {MAX,MAX,4,2  ,6  ,0}    };    MiniSpanTree_Prim(ppGraphMatrix, VERNUM);    PrintGraph(ppGraphMatrix);    //DestroyGraphMatrix(ppGraphMatrix, nVertexNum);//destory the storage matrix    //ppGraphMatrix = NULL; //graph's edgesstatic TEdge GraphEdgeArray[EDGENUM + 1] ={{0, 0, 0, 0},//no use, convenient for count{1, 2, 6, 0},{1, 3, 1, 0},{1, 4, 5, 0},{2, 3, 5, 0},{3, 4, 5, 0},{2, 5, 3, 0},{3, 5, 6, 0},{3, 6, 4, 0},{4, 6, 2, 0},{5, 6, 6, 0}}; //graph's vertexesstatic TAdjVertexNode GraphVertexArray[VERNUM + 1] ={{0, NULL},//no use{1, NULL},{2, NULL},{3, NULL},{4, NULL},{5, NULL},{6, NULL}};MiniSpanTree_Kruskal(GraphEdgeArray, GraphVertexArray);for (int i = 0; i < EDGENUM + 1; i++){if (1 == GraphEdgeArray[i].nFlag){cout << GraphEdgeArray[i].nVertexValue << endl;}}getchar();    getchar();    //BFS and DFS     cout << "Please enter the sequence number for all the vertexes in the graph." << endl;    int nNodesNum = 0;    cin >> nNodesNum;    int *pVertexesFlagArray = new int [nNodesNum + 1];    for (int i = 1; i <= nNodesNum; i++)    {        pVertexesFlagArray[i] = 0;    }        TVertexNode* pGraphStorageArray = CreatGraph(nNodesNum);    DepthFirstTraveralGraph(nNodesNum, pVertexesFlagArray, pGraphStorageArray);    getchar();} /*int** CreatGraphMatrix(int nVertexNum){int** ppGraphMatrix = new int* [nVertexNum];for (int i = 0; i < nVertexNum; i++){ppGraphMatrix[i] = new int [nVertexNum];for (int j = 0; j < nVertexNum; j++){cin >> ppGraphMatrix[i][j];}}return ppGraphMatrix;}void DestroyGraphMatrix(int** ppGraphMatrix, int nVertexNum){for (int i = 0; i < nVertexNum; i++){delete [] ppGraphMatrix[i];}ppGraphMatrix = NULL;}*/

    最新回复(0)