簡體   English   中英

C中具有鄰接表的圖形實現

[英]graph implementation with adjacency lists in C

我剛開始學習C,並且作為一種自學練習,我正在C中實現數據結構和算法。現在,我正在研究圖形,這是它的數據結構表示。

typedef int graphElementT;
typedef struct graphCDT *graphADT;

typedef struct vertexTag
{
    graphElementT element;
    int visited;
    struct edgeTag *edges;
    struct vertexTag *next; 
} vertexT;

typedef struct edgeTag
{
    int weight;
    vertexT *connectsTo;
    struct edgeTag *next;
} edgeT;

typedef struct graphCDT
{
    vertexT *vertices;
} graphCDT;

我在該圖中添加了addVertex函數。

int addVertex(graphADT graph, graphElementT value)
{
    vertexT *new = malloc(sizeof(*new));

    vertexT *vert;
    new->element = value;
    new->visited = 0;
    new->edges = NULL;
    new->next = NULL;

    int i = 0;

    for(vert=graph->vertices; vert->next != NULL; vert=vert->next)
    {
        if(vert->element == value)
        {
            printf("already exists\n");
            return 0;
        }
    }   

    vert->next = new;

    //free(new);
    printf("\ninserted %d\n", vert->element);   

    return 1;       
}

除三件事外,這工作正常。

  1. 如果新添加的頂點與列表中的最后一個頂點相同,則無法看到它。 為了防止這種情況,我將for循環限制條件更改為vert != NULL ,但這產生了段錯誤。

  2. 如果我嘗試釋放臨時分配的指針,它將通過指針重置內存指針,這會在頂點列表的末尾添加無限循環。 有沒有辦法釋放指針而不重寫它指向的內存? 還是真的不需要釋放指針?

  3. 破壞圖形也意味着破壞每個邊緣和頂點嗎? 還是有更好的方法?

同樣,如果這種用於圖形的數據結構不是一個好的結構,並且有更好的實現,我希望指出這一點。

1個

如果將限制條件更改為vert!= NULL,並且如果循環以vert == NULL結束,即,則不存在要添加的頂點,那么您將在閱讀下一條語句:

vert->next = new;

這意味着您正在訪問NULL,vert指針,因此是段錯誤。

現在,允許檢查最后一個元素是否不是要添加的頂點,並防止段錯誤,請執行以下操作:

for(vert=graph->vertices; vert->next != NULL; vert=vert->next)
{
    if(vert->element == value)
    {
        printf("already exists\n");
        return 0;
    }
}   

if(vert->element == value)
    {
        printf("already exists\n");
        return 0;
    }

vert->next = new;

2

臨時“新”指針是分配給您添加的頂點的內存位置。它不會被釋放,因為釋放它意味着您刪除了剛剛添加的頂點:O。

3

是的,破壞圖的本質是一樣的。

將鏈表實現為圖的鄰接表實現始終是一個好習慣。盡管您始終可以使用c ++“ 2D Vector”來實現它。

這是您可以使用的有效的addVertex函數。 我將原樣保留原樣。 我添加了main(),您可以在其中給命令行參數進行測試。

int addVertex(graphADT graph, graphElementT value)
{
   vertexT *tmpvert , *vert ;
   vert=graph->vertices ;
  /*check to see whether we really need to create a new vertex*/
   tmpvert = vert;
     while(tmpvert != NULL)
     {
       /* U can put a debug printf here to check what's there in graph:
        *  printf("tmpvert->elem=%d   ", tmpvert->element);
        */
        vert = tmpvert;
        if(tmpvert->element == value)
             return 0;
        tmpvert=tmpvert->next ;
    }
   /*If we are here , then we HAVE to allocate memory and add to our graph.*/
   tmpvert = (vertexT*)malloc(sizeof(vertexT));
   if ( NULL == tmpvert )
        return 0; /* malloc failure */
   tmpvert->element = value;
   tmpvert->visited = 0;
   tmpvert->edges = NULL;
   tmpvert->next = NULL;

   if ( NULL == vert )
        graph->vertices = tmpvert; /*Notice that I dont use virt=tmpvert */
   else
        vert->next = tmpvert; /*putting stuff in next is fine */

    return 1;
/* Dont try printing vert->element here ..vert will be NULL first time */
/*return code for success is normally 0 others are error.
 *That way you can have your printfs and error code
 *handling outside this function.But its ok for a test code here */
}

現在用於測試的主要()代碼段:

int main (int argc , char* argv[]) {
        graphADT graph ;
        graph =(graphADT) malloc ( sizeof(struct graphCDT) );
        graph->vertices = NULL;
        while ( --argc >0)
        {
                int value = atoi(argv[argc]);
                addVertex(graph,value);
        }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM