簡體   English   中英

打印時無限循環的循環列表

[英]Circular list in infinite loop while printing

我有一個問題,打印循環列表處於無限循環中。 在代碼中,我創建了一個 function,它接收一個值 n,即要插入列表中的元素數量和一個向量 v。然后我遍歷向量的每個元素,並根據大小將其添加到列表中的 n。 我不相信我對那個代碼塊有問題,因為錯誤是在打印過程中發生的,只有當它到達最后一個節點時

#include <stdio.h>
#include <stdlib.h>

struct circular_list {
    int info;
    struct circular_list *prox;
};
typedef struct circular_list CircularList;

CircularList* startList(CircularList *L){
    return NULL;
}

void printList(CircularList *L){
    CircularList *p=L;  

    if (p==NULL)
        printf("\nList is empty");
    else{
        do{
            if (p->prox==L) 
                printf("%d", p->info);
            else
                printf("%d -> ", p->info);
            p = p->prox;
        }while(p!=L);       
    }
    printf("\n");
}


CircularList *build(int n, int *v)
{
    CircularList *head = NULL;
    for (int i = 0; i < n; i++)
    {
        CircularList *auxList = (CircularList*)malloc(sizeof(CircularList));
        auxList->info = v[i];
        if (head == NULL) {
            auxList->prox = auxList;
        } else {
            auxList->prox = head;
        }
       
        head = auxList;
    }
    return head;
}

int main() {
    CircularList* list;
    int vector[5] = {13, 38, 21, 71, 21};

    list = startList(list);
    list = build(5, vector);
    printList(list);

    return 0;
}

誰能幫我?

(編輯)

我像這樣修改了main()來調試。 問題是build()代碼; 數組中的第一項,即您到達的最后一個列表節點,指向其自身。

int main() {

    CircularList* list;
    int vector[5] = {13, 38, 21, 71, 21};

    list = startList(list);
    list = build(5, vector);
    // printList(list);

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    printf("list node info: %d \n", list->info);
    printf("list node prox: %p \n", list->prox);
    list = list->prox;

    return 0;
}

output:

list node info: 21
list node prox: 0x7f8ae8405c50
list node info: 71
list node prox: 0x7f8ae8405c40
list node info: 21
list node prox: 0x7f8ae8405c30
list node info: 38
list node prox: 0x7f8ae8405c20
list node info: 13
list node prox: 0x7f8ae8405c20
list node info: 13
list node prox: 0x7f8ae8405c20
list node info: 13
list node prox: 0x7f8ae8405c20
list node info: 13
list node prox: 0x7f8ae8405c20

該程序的 output 開頭為:

21 -> 71 -> 21 -> 38 -> 13 -> 13 -> 13 -> 13 -> 13 -> 13

由此,我們可以看到列表沒有正確構建。 創建的第一個節點指向自身,function 沒有返回預期的頭節點。

事實上,該列表是反向鏈接的,如果您更改向量的值,則更容易看到:

int vector[5] = {13, 38, 21, 71, 51};
51 -> 71 -> 21 -> 38 -> 13 -> 13 -> 13 -> 13 -> 13 -> 13

這是一個有效的 function,我們在其中隔離頭節點。

CircularList *build(int n, int *v)
{
    CircularList *head = NULL;
    CircularList *current = NULL;

    for (int i = 0; i < n; i++) {
        CircularList *auxList = malloc(sizeof *auxList);
        auxList->info = v[i];

        if (head == NULL) {
            head = auxList;
        } else {
            current->prox = auxList;
        }

        current = auxList;
    }

    current->prox = head;

    return head;
}

緩慢的一天,所以這里是你的代碼的重寫。 不要忘記您必須使用free()堆存儲來防止 memory 泄漏。

注意結構的重命名:節點就是節點。 線性LL 相比,它是使它成為循環LL 的代碼。 一個節點是一個節點是一個節點......一個節點不是(通常)一個列表......

#include <stdio.h>
#include <stdlib.h>

typedef struct node { // combine things. Don't write more lines of code.
    int info;
    struct node *prox;
} node_t; // short & sweet name

node_t *printit( node_t *L ) {
    // think about re-using as much code as you can
    char *use = "\nList is empty"; // set up defaults in case they are used.
    if( L ) {
        node_t *p = L;
        use = ""; // default
        do {
            printf( "%s%d", use, p->info );
            use = " -> "; // replaced
        } while( (p = p->prox) != L ); // combine things
        use = ""; // to output only a LF
    }
    puts( use );
    return L; // magic can happen. see 'main()'
}

node_t *freeit( node_t *p ) { // Missing from your code
    while( p && p != p->prox ) {
        node_t *pDel = p->prox;
        p->prox = p->prox->prox;
        free( pDel );
    }
    free( p );
    return NULL;
}

node_t *buildit( int n, int *v ) {
    node_t *head = NULL, *tail = NULL;

    for( int i = 0; i < n; i++ ) {
        node_t *p = malloc( sizeof *p );
        /* omitting test for NULL */ // be explicit
        p->info = v[i];

        // combine what you can to avoid too much code
        // use the power of C syntax
        if( head == NULL )
            head = tail = p->prox = p;
        else
            (tail = tail->prox = p)->prox = head;
    }

    return head;
}

int main() {
    // use short, meaningful names in trivial functions
    int v[5] = { 13, 38, 21, 71, 21 };

    node_t *l = buildit( sizeof v/sizeof v[0], v );
    printit( l );
    l = freeit( l ); // don't forget about this!
    // setting 'l' to NULL ensures it is NULL if accidentally used again

    /* more code ?? */

    // and a bit of magic...
    freeit( printit( buildit( sizeof v/sizeof v[0], v ) ) );

    return 0;
}
13 -> 38 -> 21 -> 71 -> 21
13 -> 38 -> 21 -> 71 -> 21

暫無
暫無

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

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