0

こんにちは、一般的なリンク リストを実装しようとしています。次のコードを使用して動作するものがありますが、グローバル ポインター (curr および root) への依存を削除して、複数のリンク リストを定義できるようにする明白で適切な方法がわかりません。私が c++ を使用していた場合、おそらく全体をクラスにラップするだけですが、そのままでは、root と curr を手動で処理し、それらを必要とする関数に渡すソリューションが 1 つしかありません。これよりも良い方法があると確信しているので、どうすればよいでしょうか。ありがとう

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

struct Node{
        int value;
        struct Node *next;
};

struct Node * curr = NULL;
struct Node * root = NULL;

struct Node * createList(int val){
    struct Node *n = malloc(sizeof(struct Node));

    if(n==NULL){
        printf("Node creation failed\n");
        return NULL;
    }

    n->value = val;
    n->next = NULL;

    root=curr=n;
    return n;
}

struct Node * extendList(int val, bool end){

    if(curr == NULL){
        return createList(val);
    }

    struct Node * newNode = malloc(sizeof(struct Node));
    if(newNode==NULL){
        printf("Node creation failed\n");
        return NULL;
    }
    newNode->value = val;
    newNode->next = NULL;

    if(end){
        curr->next = newNode;
        curr = newNode;
    }
    else{
        newNode->next = root;
        root=newNode;
    }
    return curr;
}

void printList(void){
    struct Node *ptr = root;
    while(ptr!=NULL){
        printf("%d\n",ptr->value);
        ptr = ptr->next;
    }
    return;
}

struct Node * pos_in_list(unsigned int pos, struct Node **prev){
    struct Node * ptr = root;
    struct Node * tmp = NULL;
    unsigned int i = 0;
    while(ptr!=NULL){
        if(i == pos){
            break;
        }
        tmp = ptr;
        ptr=ptr->next;
        i++;
    }

    *prev = tmp;
    return ptr;
}

void deletefromlist(int pos){
    struct Node * del = NULL;
    struct Node * prev = NULL;

    del = pos_in_list(pos,&prev);
    if(del == NULL)
    {
        printf("Out of range\n");
    }
    else
    {
        if(prev != NULL)
            prev->next = del->next;

        if(del == curr)
        {
            curr = prev;
        }
        else if(del == root)
        {
            root = del->next;
        }
    }

    free(del);
    del = NULL;
}

void deleteList(){
    struct Node * del = root;
    while(curr!=NULL){
        curr = del->next;
        free(del);
        del=curr;
    }
    root = NULL;
    curr = NULL;
}

int main(void)
{
    int i;

    for(i=0;i<10;i++){
        extendList(i,true);
    }

    for(i=10;i>0;i--){
        extendList(i,false);
    }

    printList();

    deletefromlist(5);

    printList();

    deleteList();

    return 0;
}
4

5 に答える 5

1

通常、これを行う方法は、各関数にリンク リスト ポインターの引数を与えることです。このような:

struct Node * extendList(struct Node * head, int val, bool end){

    if(head == NULL){
        return createList(val);
    }

    struct Node * newNode = malloc(sizeof(struct Node));
    if(newNode==NULL){
        printf("Node creation failed\n");
        return NULL;
    }
    newNode->value = val;
    newNode->next = NULL;

    struct Node * tail = head;

    while (tail->next) tail = tail->next;

    tail->next = newNode;
    tail = newNode;
    return newNode; // return the new node
}

これにより、グローバルポインターの必要がなくなり、任意の数のリストが可能になります。実際、このコンテキストではグローバル変数の使用を避けることを強くお勧めします。

あなたがチェックアウトできるリンクされたリストの実装のレビューを提出しました。あなた自身の実装に当てはまるかもしれない批判をチェックしたいかもしれません。

于 2013-07-10T17:28:00.517 に答える