1. 程式人生 > >拓撲排序演算法實現可執行

拓撲排序演算法實現可執行

#include <stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT  10


#define MAX 20
typedef int VertexType;
typedef struct ArcNode//表結點
{
    int adjvex;//弧所指向的頂點的位置
    struct ArcNode *nextarc;
}ArcNode;
typedef struct VNode//頭結點
{
    VertexType data;//頂點資訊
    ArcNode *firstarc;//指向第一條依附該弧的頂點指標
}VNode,*AdjList;


typedef struct
{
    AdjList vertices;
    int vexnum;//圖的**當前**頂點數
}ALGraph;
typedef struct//棧的定義
{
    int *base;
    int *top;
    int stacksize;
}SqStack;
/////////棧的操作函式定義
void initialStack(SqStack *s)
{
    s->base=(int *)malloc(STACK_INIT_SIZE*sizeof(int));
    if(!s->base) exit(0);
    s->top=s->base;
    s->stacksize=STACK_INIT_SIZE;
}
void Push(SqStack *s,int e)
{
    if(s->top-s->base>=s->stacksize)
    {
        s->base=(int *)realloc(s->base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(int));
        if(!s->base) exit(0);
        s->top=s->base+s->stacksize;
        s->stacksize+=STACKINCREMENT;
    }
    *(s->top)++=e;
}
void Pop(SqStack *s,int *e)
{
    if(s->top==s->base) exit(0);
    *e=*--(s->top);
}
void GetTop(SqStack *s,int *e)
{
    if(s->top==s->base) exit(0);
    *e=*(s->top-1);
}
int StackEmpty(SqStack *s)
{
    if(s->base==s->top)
        return(1);
    else
        return(0);
}
/////建立圖的鄰接矩陣
void CreatAjacentMatrix(int *array,int n)//建立鄰接矩矩陣(n行n列)
{
    int a;
    int i,j,flag=0;
    printf("請輸入一個%d行%d列的關於圖的鄰接矩陣:\n",n,n);
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        {
            scanf("%d",&a);
            *(array+i*n+j)=a;
        }    
}
void PrintAjacentMatrix(int *array,int n)
{
    int i,j;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
            printf("%5d ",*(array+i*n+j));
        printf("\n");
    }
}


////將鄰接矩陣匯出為圖的鄰接表形式
void CreatAdjList(int *array,int n,ALGraph *G)
{
    int i,j;
    ArcNode *p;//表結點
    G->vexnum=n;//初始化頂點數
    G->vertices=(VNode *)malloc((n+1)*sizeof(VNode));//頭結點陣列,開闢n+1長度的陣列空間
    for(i=1;i<=n;i++)//初始化頭結點陣列
    {
        G->vertices[i].data=i;
        G->vertices[i].firstarc=NULL;
    }
    //////////
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        {
            if(*(array+i*n+j)==1)
            {
                p=(ArcNode *)malloc(sizeof(ArcNode));
                p->adjvex=j+1;
                p->nextarc=G->vertices[i+1].firstarc;
                G->vertices[i+1].firstarc=p;
            }
        }
}


/*void FindInDegree(ALGraph G,int *indegree)//對頂點求入度
{
    int i,j;
    ArcNode *p;
    for(i=1;i<=G.vexnum;i++)
        indegree[i]=0;//indispensable
    for(i=1;i<=G.vexnum;i++)//對每個結點跑完整個鄰接表
        for(j=1;j<=G.vexnum;j++)
            for(p=G.vertices[j].firstarc;p;p=p->nextarc)
                if(G.vertices[i].data==p->adjvex)//==
                  {indegree[i]++; printf("%d\n",p->adjvex);
}  
                    
}*/
 void FindInDegree(ALGraph G,int *indegree){
   ArcNode *p=NULL; 
   int x=0;
 for(int i=1;i<=G.vexnum;i++)
        indegree[i]=0;
 for(int i=1; i<G.vexnum; i++) {  
              
 
                p=G.vertices[i].firstarc;
                   while(p!=NULL) {        
                 x=p->adjvex;
                 printf("%d\n",x);
                    indegree[x]++;
                    p=p->nextarc;


                }


            }
 }
/////////拓撲排序演算法
int TopologicalSort(ALGraph G)
{
    //有向圖採用鄰接表儲存結構
    //若G無迴路,則flag=0,輸出G的頂點的一個拓撲序列,否則給出該有向圖有迴路的提示.
    int i,count,k;
    int *indegree=(int *)malloc((G.vexnum+1)*sizeof(int));
    SqStack S;
    ArcNode *p;
    FindInDegree(G,indegree);//對頂點求入度indegree[G.vexnum]
    initialStack(&S);//為避免重複檢測入度為0的頂點,可另設一棧暫存放所有入度為0的頂點
    for(i=1;i<=G.vexnum;i++)
        if(!indegree[i])
            Push(&S,i);//0入度點進棧
    count=0;//對輸出頂點計數,作為判斷是否有迴路的根據
    while(!StackEmpty(&S))
    {
        Pop(&S,&i);
        printf("%d  ",i);//輸出i號頂點並計數
        count++;
        for(p=G.vertices[i].firstarc;p;p=p->nextarc)
        {
            k=p->adjvex;//表結點的資料域,即對i號頂點的每個鄰接點的入度減1
            if(!(--indegree[k]))//若入度減少為0,則入棧
                Push(&S,k);
        }
    }
    if(count<G.vexnum)//該有向圖有迴路
        return 0;
    else
        return 1;
}
int main()
{
    int n;
    int *A;
    ALGraph G;
    printf("請輸入你想建立的鄰接矩矩陣的行列數(即頂點數):\n");
    scanf("%d",&n);
    A=(int *)malloc(n*n*sizeof(int));
    CreatAjacentMatrix(A,n);
    printf("請輸出圖的鄰接矩陣A:\n");
    PrintAjacentMatrix(A,n);
    CreatAdjList(A,n,&G);
    printf("該有向圖的一個拓撲排序結果如下所示:\n");
    if(TopologicalSort(G))
        printf("\n");
    else
        printf("該有向圖有迴路!\n");
        return 0;
}

相關推薦

排序演算法實現執行

#include <stdio.h> #include <stdlib.h> #define STACK_INIT_SIZE 100 #define STACKINCREMENT  10 #define MAX 20 typedef int Vert

排序實現_TopoSort

row cal struct clas stream spa data- throw cto 拓撲排序是求一個AOV網(頂點代表活動, 各條邊表示活動之間的率先關系的有向圖)中各活動的一個拓撲序列的運算, 可用於測試AOV 網絡的可行性. 整個算法包含三步:

排序(佇列實現)

什麼是拓撲排序呢?就是將一個有向無環圖中所有頂點在不違反先決條件關係的前提下排成線性序列的過程稱為拓撲排序。 學拓撲排序有什麼用呢?當然有用啦~。比如說學校排課的時候,會考慮到有的課程需要先修。我們學完C程式設計這門課,有了程式設計基礎,然後才能學習資料結構。大學要修很多門課程的,人為的

排序 bfs實現

 程式碼如下: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <vector> #in

如何理解排序演算法(轉)

       對於一條有向邊(u,v),定義u < v;滿足所有這樣條件的結點序列稱為拓撲序列。拓撲排序就是求一個有向圖的拓撲序列的演算法。一個有向圖頂點的拓撲序列不是惟一的。並不是任何有向圖的頂點都可以排成拓撲序列,有環圖是不能排的。 例子:比如排課問題,比如士兵排隊

確定比賽名次(hdu-1285)(排序佇列實現

分析: 就是找出是否存在拓撲排序。 每次從該集合中取出(沒有特殊的取出規則,隨機取出也行,使用佇列/棧也行,下同)一個頂點,將該頂點放入儲存結果的List中。 緊接著迴圈遍歷由該頂點引出的所有邊,

資料結構--C語言--圖的深度優先遍歷,廣度優先遍歷,排序,用prime演算法實現最小生成樹,用迪傑斯特拉演算法實現關鍵路徑和關鍵活動的求解,最短路徑

實驗七  圖的深度優先遍歷(選做,驗證性實驗,4學時) 實驗目的 熟悉圖的陣列表示法和鄰接表儲存結構,掌握構造有向圖、無向圖的演算法 ,在掌握以上知識的基礎上,熟悉圖的深度優先遍歷演算法,並實現。 實驗內容 (1)圖的陣列表示法定義及

HDU 1285--確定比賽名次【排序 &amp;&amp; 鄰接表實現

eat priority tex eof greate topsort -- str spa 確定比賽名次 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/

排序的原理及其實現

還需要 play 結果集 3.0 硬幣 tps 進行 程序 微軟雅黑 本文將從以下幾個方面介紹拓撲排序: 拓撲排序的定義和前置條件 和離散數學中偏序/全序概念的聯系 典型實現算法 Kahn算法 基於DFS的算法 解的唯一性問題 實際例子 取材自以下材料:

排序判斷是否有環(正環負環無所謂))

資料結構AOE網 和AOV-網一節    意義就是: 給出一些事件和活動 (圖),該事件進行的前提條件是,所有以該事件為後繼的活動已經完成(頂點進行的前提條件是,其作為後繼的邊全部完成) 給這些事件排個序,使得事件進行過程不衝突 如果衝突 &nb

圖——基本的圖演算法(三)排序

圖——基本的圖演算法(三)拓撲排序 1. 基本概念 對於一個有向無環圖G = (V, E)來說,其拓撲排序就是G中所有頂點的一種線性排序,這種排序滿足如下條件:如果圖G中包含邊(a, b),即由頂點a指向頂點b的有向邊,那麼在G的拓撲排序中,頂點a一定處於頂點b前面(因此如果有向

【Python排序搜尋基本演算法】之排序

   拓撲排序是對有向無環圖的一種排序,滿足如下兩個條件: 1.每個頂點出現且只出現一次; 2.若A在序列中排在B的前面,則在圖中不存在從B到A的路徑。 如上的無環有向圖,v表示頂點:v=['a','b','c','d','e'],e表示有向邊:e=[('a

排序|Topological Sort類演算法題心得(PYTHON版)

拓撲排序 尋找專案之間依賴順序的過程稱為拓撲排序(topological sorting)。   首先要了解有向無環圖|Directed Acyclic Graph: 用字典表示:G = { 'a':'bce', 'b':'d','c':'d','d':'','e':'cd'} Key

排序-List graph[]實現

import java.util.*; public class Tuopupaixu2 { public static void main(String args[]){ Scanner in=new Scanner(System.in); while(in.has

藍書(演算法競賽進階指南)刷題記錄——BZOJ2200 道路與航線(堆優化dijkstra+排序

題目:bzoj2200. 題目大意:給出一張圖,其中無向邊權一定為正,且不可能有一個有向邊組成的環. 我們可以直接寫一個SPFA上去,發現TLE了,然後dijkstra又不能處理負權邊. 所以是時候拿出準備已久的神奇A*演算法了. 我們先將無向邊輸入,將所有無向連通塊用dfs打上

資料結構與演算法之------排序與關鍵路徑

一.拓撲排序 這裡請結合參考部落格學習(在後面) 拓撲排序(無環圖的應用) 在一個表示工程的有向圖中,有頂點表示活動,用弧表示活動之間的優先關係,這樣的有向圖為頂點表示活動的網,我們稱為AOV(Activity On Vertex)網。 AOV網中的弧表示活動之間存在的某種制約關

演算法排序

演算法:拓撲排序 拓撲排序 什麼是拓撲排序   其實在寫這篇部落格的時候,我也是以一個學習者的角度出發的,目的就是想讓自己理解和初步掌握拓撲排序。   維基百科的定義如下:       在電腦科學領域,有向圖頂點的線性排序就是其拓撲排序,例如,圖形的頂點可以表示要執行的任務,並且邊可以表示一個任務必

排序達性統計

ACM題集:https://blog.csdn.net/weixin_39778570/article/details/83187443 拓撲排序 把入度為0的點加入列隊,這些點一點在拓撲排序的前面。遍歷列隊依次出隊,出隊的點加入拓撲序,把出隊的點的兒子的入度都減少一,可以近似認為該父節

資料結構與演算法——有向圖鄰接表輸出其排序序列

  測試資料 輸入: 12 16 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c1 c4 c1 c2 c1 c3 c1 c12 c4 c5 c2 c3 c3 c5 c3 c7 c5 c7 c3 c8 c9 c12 c9 c10 c10 c12 c

排序以及迪傑斯特拉演算法和弗洛伊德演算法的一些例子(天勤資料結構)

拓撲排序核心演算法     在一個有向圖中找到一個拓撲排序的過程如下:     1)從一個有向圖中選擇一個沒有前驅(入度為0)的頂點輸出;     2)刪除1)中的頂點,並刪除從該頂點出發的全部邊;