Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中的链表实现中打印额外的0而不删除前面的节点_C_Linked List_Singly Linked List - Fatal编程技术网

在C中的链表实现中打印额外的0而不删除前面的节点

在C中的链表实现中打印额外的0而不删除前面的节点,c,linked-list,singly-linked-list,C,Linked List,Singly Linked List,我的代码有两个独立的(尽管可能是连接的)问题,其中一个问题是,当我打印出链表时(无论我是将节点推到前面还是推到后面),它会在链表的开头额外打印一个0。我看到了一篇类似的文章,但是push方法的实现是不同的,因为它没有将head作为参数,所以我在main()方法中定义了head: struct node *head = NULL; 我的链表实例化如下所示 struct node *temp, *ptr; temp=(struct node*)malloc(sizeof(struct node))

我的代码有两个独立的(尽管可能是连接的)问题,其中一个问题是,当我打印出链表时(无论我是将节点推到前面还是推到后面),它会在链表的开头额外打印一个0。我看到了一篇类似的文章,但是push方法的实现是不同的,因为它没有将head作为参数,所以我在main()方法中定义了head:

struct node *head = NULL;
我的链表实例化如下所示

struct node *temp, *ptr;
temp=(struct node*)malloc(sizeof(struct node));
if(temp==NULL) {
    exit(0);
}
temp->next=NULL;
if(head==NULL) {
    head=temp;
} else {
    ptr=head;
    while(ptr->next!=NULL) {
        ptr=ptr->next;
    }
    ptr->next=temp;
    ptr->data=NULL;
}
我遇到的问题是,我不确定这个问题是在print方法、pushfront方法还是链表实例化中

有关守则如下:

case PUSH_FRONT: ;  // push onto front of list
    struct node *temp1;
    temp1=(struct node*)malloc(sizeof(struct node));
    if(temp1==NULL) {
        break;
    }
    temp1->next=NULL;
    temp1->data=val;
    if(head==NULL) {
        head=temp1;
    } else {
        temp1->next=head;
        head=temp1;
    }
    break;
case POP_FRONT: ;   // remove from front of list
    // If list is empty, do nothing.
    struct node *ptr2;
    ptr2=(struct node *)malloc(sizeof(struct node));
    if(ptr2==NULL) {
        break;
    }
    if(head==NULL) {
        break;
    } else if(head->next==NULL) {
        ptr2=head;
        head=head->next;
        free(ptr2);
    }
    break;
我的另一个问题(尽管我仍然相信这个问题在别处)是我的pop-front方法完全不起作用,我猜这与链表的初始实例化有关。有关守则如下:

case PUSH_FRONT: ;  // push onto front of list
    struct node *temp1;
    temp1=(struct node*)malloc(sizeof(struct node));
    if(temp1==NULL) {
        break;
    }
    temp1->next=NULL;
    temp1->data=val;
    if(head==NULL) {
        head=temp1;
    } else {
        temp1->next=head;
        head=temp1;
    }
    break;
case POP_FRONT: ;   // remove from front of list
    // If list is empty, do nothing.
    struct node *ptr2;
    ptr2=(struct node *)malloc(sizeof(struct node));
    if(ptr2==NULL) {
        break;
    }
    if(head==NULL) {
        break;
    } else if(head->next==NULL) {
        ptr2=head;
        head=head->next;
        free(ptr2);
    }
    break;
你应该发布有人可以下载和编译的代码。什么时候 需要数据文件或问题说明。代码片段是 不太好

通过查看标签
PRINT\u list

我的想法是这样的

  • 列表是节点的集合。在java中,列表甚至被称为集合。在C++列表中称为容器。当您为链表编写代码时,就像它是一个
    节点一样,您将得到更多的工作和更少的结果
  • 作为将节点用作列表的直接结果,在实例化代码中,这里有3个指针来管理列表:
    head
    temp
    ptr
    ,这太多了。想象一下,如果有3个列表
  • 只指向一个方向的指针的列表更难编程,而且比指向下一个和上一个节点的指针的列表用处要小得多。如果是你的决定,你应该重新考虑。如果额外指针的空间不是问题,则很难证明不使用2个指针是合理的。想象一下一个库的列表,一条路径,一个播放列表,所有经典的例子:能够在两个方向上导航是非常困难的
  • 使用switch()是不常见的。为什么不直接使用函数呢
回到你的代码 在这里你写
ptr->data=NULL
我们可能认为
数据
是一个指针,但在您编写的列表标签中

       ptr4=head;
        while(ptr4) {
            printf("%d",ptr4->data);
            printf(" ");
            ptr4=ptr4->next;
        }
        printf("\n");
        free(ptr4);
当您在
printf()
中使用
%d
时,数据只是一个
int
。嗯,实例化中的
NULL
是,嗯,一个零

而NULL就是您正在抱怨的0

这段代码似乎比它需要的要复杂得多,也很难阅读

让我展示另一种选择

关于宣言 您可以像这样编写节点结构

typedef struct _nd
{
    int         data;
    struct _nd* next;

}   node;
因此,您可以在声明中使用
节点
,而不必一直重复
struct
。另外,为
typedef
设置约定也很有用,比如使用大写字母帮助提高可读性

正如我之前所说,列表是一组节点,它不是一个节点,而是一个节点,里面有一个指针,每个节点都有一个有效负载,一些数据,通常是一个指针。例如,考虑

列表结构的另一个示例 这里的列表是,
list
。每个列表都有
大小
限制
,甚至还有一个
名称
。我将数据保存为
int
,但不好:您真的希望它作为指针,可能是
(void*)

为什么?因为通过这种方式,您可以在任何地方重用代码,而无需进行任何更改

如何使用这样的列表? 使用类似于这些可能的原型的函数

List*      _create(const char*);
int        _define_max(List* l, const unsigned);
List*      _delete(List*);
int        _empty(List*);
int        _get_max(List*);
List*      _insert_begin(int, List*);
List*      _insert_end(int, List*);
int        _insert_your_way(List*, int(*)(int,int));
int        _print(List*);
int        _print_your_way(List*, int(*)(int,int));
List*      _remove(int, List*);
int        _size(List*);
我将在下面发布一个运行示例,以便您可以测试或询问您需要的案例。但这是正常的。只有这两个功能不太常见,但更有用:

int        _insert_your_way(List*, int(*F)(int,int));
int        _print_your_way(List*, int(*F)(int,int));
这里您可以传递一个函数,如
qsort()
函数中的函数,然后在该位置插入节点,使用函数F()比较节点。其效果是,只需为“打印”或“插入”函数提供不同的函数,就可以按任意顺序插入(或列出)节点,而不改变列表代码。C,那么,C++,每个人都这样做,所以我们也可以:< /P> 用于实例化此类列表的代码 您可能会发现,以这种方式编写代码更容易维护或阅读代码。而
列表
作为一个容器更具表现力:关于列表的元数据包含在列表中。无需使用
ptr
head
temp
size
或悬挂在
main()中的其他控件

要创建一个列表,您只需编写,如示例中所示

    List* first = _create("The First List");
在节点处插入节点 正如我告诉你的,这只是一个玩具,一个例子。实际上,为了得到一个通用代码,您将使用void*。我在这里使用
int
作为数据,正如您所做的那样。要在上面创建的列表中插入几个节点,只需编写

    // insert 6,7,8,9,10 at the end
    for(int i = 6; i<11; i+=1 ) _insert_end(i, first);
代码(几乎没有测试)
这不是问题,但是打印列表的代码不应该分配内存。删除调用
malloc
的行和调用
free
的行。内存分配没有做任何有用的事情,如果
head
为空,它将泄漏内存。在
POP\u FRONT
中,您泄漏内存。您要么不使用
ptr2
,要么通过将
head
分配给该指针来覆盖分配块的地址。在C语言中,不需要强制转换malloc的返回,这是不必要的。请参阅:虽然没有错误,但不鼓励使用全局变量(特别是使用通用名称行
temp
ptr
),请看一看,然后请不要发布代码片段,因为它们尚未经过测试,这表明您观察到的问题存在。f后
    List* first = _create("The First List");

List*      _insert_begin(int value, List* l)
{
    if (l == NULL) return l; //no list
    if ((l->limit > 0) && (l->size == l->limit)) return l; // full
    // ok: create a node and stuff data in
    Node* nd = (Node*)malloc(sizeof(Node));
    nd->data = value; // data comes in
    nd->next = l->head; // depois vem o que estava na frente
    l->head = nd; // nd fim
    l->size = l->size + 1;
    // if it is the first node
    if (l->size == 1)l->tail = nd;
    return l;
};
    // insert 6,7,8,9,10 at the end
    for(int i = 6; i<11; i+=1 ) _insert_end(i, first);
int main(void)
{
    List* first = _create("The First List");
    _print(first);
    _define_max(first,300);
    _print(first);

    // insert 5,4,3,2,1 at the beggining
    for(int i = 5; i>0; i-=1 ) _insert_begin(i, first);
    // list again
    _print(first);

    // insert 6,7,8,9,10 at the end
    for(int i = 6; i<11; i+=1 ) _insert_end(i, first);
    // list again
    _print(first);

    printf("empty(): %d size()= %d\n",
        _empty(first),
         _size(first) );

    first = _delete(first);
    _print(first);
    return 0;    
}
List 'The First List' with 0 elements [MAX not defined yet]

List 'The First List' with 0 of 300 MAX elements

List 'The First List' with 5 of 300 MAX elements

    First:         1
     Last:         5

Elements

         1 
         2 
         3 
         4 
         5 

End of list


List 'The First List' with 10 of 300 MAX elements

    First:         1
     Last:        10

Elements

         1 
         2 
         3 
         4 
         5 
         6 
         7 
         8 
         9 
        10 

End of list

empty(): 0 size()= 10
Deleting 'The First List'
List not created!
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>

typedef struct _nda
{
    int          data;
    struct _nda* next;

}   Node;


struct _the_list
{
    char*     name;
    unsigned  size;
    unsigned  limit;
    Node*     head;
    Node*     tail;
};
typedef struct _the_list List;

List*      _create(const char*);
int        _define_max(List* l, const unsigned);
List*      _delete(List*);
int        _empty(List*);
int        _get_max(List*);
List*      _insert_begin(int, List*);
List*      _insert_end(int, List*);
int        _insert_your_way(List*, int(*)(void*));
int        _print(List*);
int        _print_your_way(List*, int(*)(void*));
List*      _remove(int, List*);
int        _size(List*);

int main(void)
{
    List* first = _create("The First List");
    _print(first);
    _define_max(first,300);
    _print(first);

    // insert 5,4,3,2,1 at the beggining
    for(int i = 5; i>0; i-=1 ) _insert_begin(i, first);
    // list again
    _print(first);

    // insert 6,7,8,9,10 at the end
    for(int i = 6; i<11; i+=1 ) _insert_end(i, first);
    // list again
    _print(first);

    printf("empty(): %d size()= %d\n",
        _empty(first),
         _size(first) );

    first = _delete(first);
    _print(first);
    return 0;    
}

List*      _create(const char* name)
{
    List* one = (List*)malloc(sizeof(List));
    one->name = (char*)malloc(1 + strlen(name));
    strcpy(one->name, name);
    one->size = 0;
    one->limit = 0;
    one->head = NULL;
    one->tail = NULL;
    return one;
};  // criar()

int        _define_max(List* l, const unsigned m)
{
    if (l == NULL) return -1;
    // new value can not be less than present size
    if (l->size > m) return -2;
    l->limit = m;
    return m;
};

List*      _delete(List* l)
{
    if (l == NULL) return NULL;
    printf("Deleting '%s'\n", l->name);
    free(l->name);
    if (l->size == 0)
    {
        free(l);
        return NULL; // empty
    };  // if()

    Node* node = l->head;
    do
    {
        Node* p = node->next; 
        free(node);
        node = p;
    } while (node != NULL);
    return NULL;
};

int        _empty(List* L)
{
    if (L == NULL) return -1;
    return (L->size == 0); 
};

int        _get_max(List* L)
{
    if (L == NULL) return -1;
    return (int)L->limit;
};

List*      _insert_begin(int value, List* l)
{
    if (l == NULL) return l; //no list
    if ((l->limit > 0) && (l->size == l->limit)) return l; // full
    // ok: create a node and stuff data in
    Node* nd = (Node*)malloc(sizeof(Node));
    nd->data = value; // data comes in
    nd->next = l->head; // depois vem o que estava na frente
    l->head = nd; // nd fim
    l->size = l->size + 1;
    // if it is the first node
    if (l->size == 1)l->tail = nd;
    return l;
};

List*      _insert_end(int value, List* l)
{
    if (l == NULL) return l;
    if ((l->limit > 0) && (l->size == l->limit)) return l; // full
    // ok: create a node and insert at the end
    Node* nd = (Node*)malloc(sizeof(Node));
    nd->data = value;
    // first one?
    if (l->size == 0)
    {
        l->head = nd;
        nd->next = NULL;
    }
    else
    {
        nd->next = NULL; // no one after this
        (l->tail)->next = nd;
    };  // if()
    l->tail = nd; // nd is tail now
    l->size = l->size + 1;
    // of this is the first node
    if (l->size == 1)l->head = nd;
    return l;
};

int        _insert_your_way(List* L, int(*F)(void*))
{
    return 0;
};

int        _print(List* l)
{
    if (l == NULL)
    {
        printf("List not created!\n");
        return -1;
    };

    if (l->limit > 0)
    {
        printf("\nList '%s' with %d of %d MAX elements\n",
            l->name,
            l->size,
            l->limit
            );
    }
    else
    {
        printf("\nList '%s' with %d elements [MAX not defined yet]\n",
            l->name,
            l->size
            );
    }
    if (l->size < 1) return 0;
    // assume data as just an int
    Node* p = l->head;
    printf("\n    First:%10d\n", l->head->data);
    printf("     Last:%10d\n", l->tail->data);
    printf("\nElements\n\n");
    do
    {
        printf("%10d \n", p->data);
        p = p->next;
    } while (p != NULL); 
    printf("\nEnd of list\n\n");
    return 0;
};  // _print()

int        _print_your_way(List* L, int(*F)(void*))
{
    return 0;
};

List*      _remove(int value, List* L)
{
    return NULL;
};

int        _size(List* L)
{
    if (L == NULL) return -1;
    return (int)L->size;
};