在使用 calloc 后检查列表数组中的单个列表是否为空的最佳方法是什么? [英] What's the best approach to check if in a array of lists a single list is empty after I used calloc?

查看:61
本文介绍了在使用 calloc 后检查列表数组中的单个列表是否为空的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,当我使用链表时,我会写:

Usually, when I use linked lists, I write:

struct node *startPtr = NULL;

所以我稍后检查它是否为NULL,如果为NULL,则表示列表为空.

so I check later if is it NULL, and if it is, it means that the list is empty.

但是在这段代码中:

struct card{
    char face[3];
    char suit[4];
};
typedef struct card Card;

struct stack{
    Card cardd;
    struct stack *nextPtr;
};
typedef struct stack Stack;

int main(){
    /*
    creation of *stacks also with calloc
    */
    Stack *topstacks = calloc(4,sizeof(Stack));    // array of lists initialized by calloc
    /*
    scanf pos1, pos2 to switch
    */
    move_card(stacks, topstacks, pos1, pos2);
}

int move_card(Stack *stacks, Stack *topstacks, unsigned int pos1, unsigned int pos2){
    Stack *prevfromPtr;
    Stack *fromPtr = &(stacks[pos1]);
    Stack *toPtr = &(topstacks[pos2]); 
    while(fromPtr->nextPtr!=NULL){
        prevfromPtr = fromPtr;
        fromPtr = fromPtr->nextPtr;
    }
    Stack *newmovingcard = calloc(1,sizeof(Stack));
    newmovingcard->cardd = fromPtr->cardd;
    newmovingcard->nextPtr = NULL; 
    if (toPtr!=NULL){                       // here I'd like to check if the list is empty and has not any item. This way it does not work because toPtr can't be NULL, it's a pointer
        while(toPtr->nextPtr!=NULL){
            toPtr = toPtr->nextPtr;
        } 
        toPtr->nextPtr = newmovingcard; 
        free(fromPtr);
        prevfromPtr->nextPtr = NULL;
        return 0;
    } else {
        toPtr->cardd = newmovingcard->cardd;
        toPtr->nextPtr = NULL;
        free(fromPtr);
        prevfromPtr->nextPtr = NULL;
        return 0;
    }
}

我有一个用calloc初始化的列表(顶部堆栈)数组.在 move_card 内的注释行中,我需要检查列表数组的单个列表是否为空.但是我不知道该怎么做.

I have an array of lists (topstacks), initialized with calloc. And in the commented line inside move_card, I need to check if the single list of the array of lists is empty. But I don't know how to do that.

这是完整的代码,但是printf的某些部分是意大利语的,为此感到抱歉: https://wtools.io/paste-code/b2gz

Here is the full code, but some parts with printf are in italian, so sorry for that: https://wtools.io/paste-code/b2gz

推荐答案

同时处理两个链表虽然很繁琐而且很烦人,但这是可行的:

Working with two linked lists simultaneously is kind of fussy and annoying, but it is doable:

int move_card(Stack **source, Stack **target, int source_pos, int target_pos) {
    // Walk through the linked list, but in every case stop one short of the
    // insertion point

    // Walk through the source chain and identify which pointer needs
    // to be manipulated.
    for (int i = 0; i < source_pos; ++i) {
        if (*source == NULL) {
            return -1;
        }

        source = &((*source)->nextPtr);
    }

    // Walk through the target chain and identify the insertion point.
    for (int i = 0; i < target_pos - 1; ++i) {
        if (*target == NULL) {
            return 1;
        }

        target = &((*target)->nextPtr);
    }

    // Capture the pointer we're actually moving
    Stack* moving = *source;

    // Skip this link in the chain by reassigning source
    *source = moving->nextPtr;

    // Capture the record that's being bumped
    Stack* bumped = *target;

    // Reassign the target
    *target = moving;

    // Re-link the bumped entry back in the chain
    moving->nextPtr = bumped;

    return 0;
}

我自由地重命名了一些东西,以使其更易于理解.请注意,它如何使用双指针,以便在必要时可以操纵原始指针.当从链表中删除第一张卡时,指向头"的指针被指向.条目必须更改.

Where I've taken the liberty of renaming a few things to make this easier to understand. Notice how it uses a double pointer so it can manipulate the original pointers if necessary. When removing the first card from a linked list, the pointer to the "head" entry must change.

这是更完整的演示",利用该代码:

Here's a more complete "demo" harness for that code:

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

struct stack {
    char card[2];
    struct stack *nextPtr;
};
typedef struct stack Stack;

Stack* make_stack(char face, char suit, Stack* nextPtr) {
    Stack* stack = calloc(1, sizeof(Stack));
    stack->card[0] = face;
    stack->card[1] = suit;
    stack->nextPtr = nextPtr;

    return stack;
}

void print_stack(Stack* stack) {
    while (stack) {
        printf("%c%c ", stack->card[0], stack->card[1]);
        stack = stack->nextPtr;
    }

    printf("\n");
}

int main(int argc, char** argv) {
    Stack* source = make_stack('A', 'S', make_stack('2', 'S', make_stack('3', 'S', NULL)));
    Stack* target = NULL;

    print_stack(source);

    move_card(&source, &target, 2, 0);

    print_stack(source);
    print_stack(target);

    return 0;
}

使用简化卡模型的地方.

Where that uses a simplified Card model.

这篇关于在使用 calloc 后检查列表数组中的单个列表是否为空的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆