图论----拓扑排序

     拓扑排序是,将有向图中每个点按照一定的顺序排列。如果有向边 vi->vj存在,那么vi结点必须出现在vj之前。

    算法思想:

    (1)首先我们利用邻接表保存图结构。

    (2)利用一个数组indegree[]数组来记录每个结点的入度。

    (3)将入度为0的点加入到堆栈 stack中。

    (4)将结点node出栈,清除node发出每一条边node->to,并将indegree[to]--。

    (5)继续寻找入度为0的点,加入栈,直到栈为空。

     时间复杂度:O(V+E)

#include <iostream>
#include <stack>
using namespace std;

const int MAXN = 1000;

struct Edge
{
	int to;
	int value;
	int next;

	Edge()
	{
		value = 0;
		next = -1;
	}
}e[MAXN*2];

int head[MAXN];
int indegree[MAXN];
int edgeNum = 0; //全局唯一标示,边的数目
int v; //结点数目

void addEdge(int from,int to)
{
    e[edgeNum].to  = to;
	e[edgeNum].next = head[from];
	head[from] = edgeNum++;
}

bool findZeroIndegree(int& vert)
{
	for ( int i = 1; i <= v; i++ )
	{
        if( indegree[i] == 0 )
		{
			vert = i;
			return true;
		}
	}
	return false;
}

void topSort()
{
   stack<int> myStack; //定义堆栈
    
   int node;
   if( findZeroIndegree(node) )
   {
           myStack.push(node);
   }
   else
   {
	   printf("无法排序!\n");
	   return ;
   }

   int count = 0;
   while ( !myStack.empty() )
   {  
	   count++;
	   node = myStack.top();
	   myStack.pop();
	   indegree[node] = -1; //标记该点已经访问过了
	   cout << node << endl;
       
	   //清除node发出的所有边
	   for ( int index = head[node]; index != -1; index = e[index].next )
	   {
              int to = e[index].to;
			  indegree[to]--;
	   }


       if( findZeroIndegree(node) )
		   myStack.push(node);

   }

   if( count != v )
	   cout << "无法排序" << endl;
   
}

int main()
{
	int n; //边数
	printf("请输入边的数目:");
	scanf("%d%d",&v,&n);
	memset(head,-1,sizeof(head));
	memset(indegree,0,sizeof(indegree));
	int from,to;
	for ( int i = 0; i < n; i++ )
	{
               scanf("%d %d",&from,&to);
		addEdge(from,to);
		indegree[to]++;
	}

	topSort();
	return 0;
}

 

你可能感兴趣的:(排序)