1. 程式人生 > >圖處理算法-Kosaraju's-算法

圖處理算法-Kosaraju's-算法

com nbsp class 數據 segment rst 非遞歸實現 非遞歸 實現

1.寫了算法課關於有向圖的作業。

用c++開辟大數組容易出segment fault,後來改用堆開辟。圖的鄰接表用了鏈表表示。

long int numVertexes = 875714;
long int numEdges;
VertexNode* adjList = new VertexNode[875714];

2.關於圖的存儲,用了鄰接鏈表存儲(用鏈表比vector數組存儲速度快多了)。

2.1 邊表

/********邊表***********/
class EdgeNode
{
public:
    long int adjvex; //邊表數據
    EdgeNode *next; //
邊表指向的下一個節點 EdgeNode(long int adj, EdgeNode *n = NULL): adjvex(adj), next(n){} };

2.2 頂點表

/*********頂點表**********/
class VertexNode
{
public:
    long int data;    //當前頂點數據
    EdgeNode *firstEdge; //頂點第一條邊
//    VertexNode(long int d, EdgeNode *fir = NULL) : data(d), firstedge(fir) {}
};

2.3 初始化圖邊時用了頭插法

/*************頭插法*************************/
    void addEdge(long int a, long int b)
    {
        EdgeNode *enode = new EdgeNode(b,NULL);
        enode->next = (adjList+a)->firstEdge;
        (adjList+a)->firstEdge = enode; 
    }

3.深度優先搜索

3.1 遞歸實現

偽代碼如下:

輸入:有向圖G和某個頂點i

1.將該頂點i標記為已訪問。

2.對邊(i,j),即頂點i的鄰接點j遍歷:

3.if 存在某個頂點j未被訪問,則對頂點j進行訪問:

DFS(G,j)

c++代碼如下:

/*---------------------第一次dfs-------------------*/
void DFS(Graph graph, long int i) 
    {
        marked[i] = true;
        
        list<long int>::iterator iter;
        for(iter = graph._storage[i].begin(); iter != graph._storage[i].end(); iter++)
        {
            long int temp = *iter;
            if(!marked[temp])
            {
                DFS(graph, temp);
            }
        }
        time++;
        ff[time-1] = i;
    }
/*---------------第二次dfs---------------*/
void DFS2(Graph graph, long int i)
    {
        marked[i] = true;
        leader[i] = s;

        list<long int>::iterator iter;
        for(iter = graph._storage[i].begin(); iter != graph._storage[i].end(); iter++)
        {
            long int temp = *iter;
            if(!marked[temp])
            {
                DFS2(graph, temp);
            }
        }
    }

3.2 非遞歸實現

偽代碼如下:

1. 棧初始化,將頂點i入棧。

2. while(棧非空)

x = 棧頂元素

3. 對於每條邊(x,j)進行遍歷:

if 存在某個頂點j未被訪問:

  將j標記為已訪問

  將j入棧

  break;

else:

  x出棧

c++代碼:

/*================第一次dfs================*/
    void dfsLoop1(Graph graph)
    {
        markedInit();
        time = 0; 
        for(long int i = length-1; i >= 0; i--)
        {
            if(!marked[i])
            {
                DFS1(graph, i);
            }
        }
    }
    void DFS1(Graph graph, long int i)
    {
        stack< VertexNode* > stack;
        stack.push(graph.adjList+i);
        marked[i] = true;
        while(!stack.empty())
        {
            VertexNode *temp = new VertexNode;
            temp = stack.top();
            EdgeNode *p = new EdgeNode(0, NULL);
            p = temp->firstEdge;
            int flag = 0;
            while(p)
            {
                if(!marked[p->adjvex])
                {
                    marked[p->adjvex] = true;
                    stack.push(graph.adjList + (p->adjvex));        
                    flag = 1;
                    break;
                }
                p = p->next;
            }
            if(!flag)
            {
                ff[time] = temp->data;
                time++;
                stack.pop();
            }
        }
    }
/*================第二次dfs================*/
    void dfsLoop2(Graph graph)
    {
        markedInit();
        time = 0;
        for(long int i = length-1; i >=0 ; i--)
        {
            if(!marked[ff[i]])
            {
                s = ff[i];
                DFS2(graph, ff[i]);
            }
        }
    }
void DFS2(Graph graph, long int i)
    {
        stack < VertexNode* > stack;
        stack.push(graph.adjList+i);
        leader[i] = s;
        marked[i] = true;
        while(!stack.empty())
        {
            VertexNode *temp = new VertexNode;
            temp = stack.top();
            marked[temp->data] = true;
            EdgeNode *p = new EdgeNode(0,NULL);
            p = temp->firstEdge;
            int flag = 0;
            while(p)
            {
                if(!marked[p->adjvex])
                {
                    marked[p->adjvex] = true;
                    stack.push(graph.adjList + p->adjvex);
                    flag = 1;
                    break;
                }
                p = p->next;
            }
            if(!flag)
            {
                leader[temp->data] = s;
                stack.pop();
            }


        }
    }

完整代碼:
https://github.com/Shinered/Kosaraju/blob/master/dfs3.cpp

圖處理算法-Kosaraju's-算法