简而言之,我应该有"1234568910".

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

typedef int DataType;    

typedef struct Node
{
    DataType data;
    struct Node *next;
} SLNode;

void ListInitiate(SLNode **head)        /* Initialization */
{
/* If there is memory space, apply the head node space and make the head pointer point to the head node */

    if((*head = (SLNode *)malloc(sizeof(SLNode))) == NULL) exit(1);
    (*head)->next = NULL;          /* set the last of the list as Null */
}


int ListLength(SLNode *head)     /* Get the size of the linked list */
{
    SLNode *p = head;             
    int size = 1;

    while(p->next != NULL)         /*count with loop*/
    {
        p = p->next;
        size ++;
    }
    return size;
}

int ListInsert(SLNode *head, int i, DataType x)

/* Insert a node that contains the data element x before the node ai (0 ≤ i ≤ size) of the linked list with header */

{
    SLNode *p, *q;
    int j;

    p = head;             /* p points to the head*/
    j = -1;               /* the initial value of j is -1*/
    while(p->next != NULL && j < i - 1)
    /* Finally let pointer p point to data element ai-1 node */
    {
        p = p->next;
        j++;
    }

    if(j != i - 1)
    {
        printf("Insert position parameter wrong!");
        return 0;
    }

    /* q points to the new node*/
    if((q = (SLNode *)malloc(sizeof(SLNode))) == NULL) exit(1);
    q->data = x;

    /* There is an error blow*/
    q->next = p->next;
    p->next = q;
    return 1;
}

int ListDelete(SLNode *head, int i, DataType *x)
/* delete the node ai of the list with a header*/
/* put the data element of the node in x. If success, return 1; if fail, return 0*/

{
    SLNode *p, *s;
    int j;
    p = head;
    j = -1;

    while(p->next != NULL && p->next->next!= NULL && j < i - 1)

    /*Finally let pointer p point to data element ai-1 node */

    {
        p = p->next;
        j++;
    }

    if(j!= i - 1)
    {
        printf("Insert position parameter wrong!");
        return 0;
    }


    s = p->next;         /*s points to ai*/
    *x = s->data; /*Assign the data field value of the node pointed by pointer s to x */
    p->next = s->next;     /* delete ai*/
    free(s);          /* free the memory space of s */
    return 1;
}

int ListGet(SLNode *head, int i, DataType *x)
/*The function of taking the data element ai is similar to deleting ai function, but do not delete the data element ai node*/
{
    SLNode *p;
    int j;

    p = head;
    j = 0;
    while(p->next != NULL && j < i)
    {
        p = p->next;
        j++;
    }

    if(j != i)
    {
        printf("The position of the parameter is wrong!");
        return 0;
    }


    *x = p->data;

    return 1;
}

void Destroy(SLNode **head)
{
    SLNode *p, *p1;

    p = *head;
    while(p != NULL)
    {
        p1 = p;
        p = p->next;
        free(p1);
    }
    *head = NULL;
}

void main(void)
{
    SLNode *head;
    int i , x;
    ListInitiate(&head);
    for(i = 0; i < 10; i++)
    {
        if(ListInsert(head, i, i+1) == 0)      /*insert ten data elements*/
        {
            printf("Error!! \n");
            return;
        }
    }

    if(ListDelete(head, 4, &x) == 0)     /* delete data element 5*/
    {
        printf("error! \n");
        return;
    }

    for(i = 0; i < ListLength(head); i++)
    {
        if(ListGet(head, i, &x) == 0)      /* take out the element*/
        {
            printf("Error! \n");
            return;
        }
        else printf("%d    ", x);        /* show data elements*/
    }

    Destroy(&head);
}

推荐答案

问题在于代码的逻辑.好的输出是代码::Blocks one.

问题在insertNode函数范围内.它的行为如下:找到第i-1个 node ,并在其之后创建一个新 node .如果是i = 0,那么在第一个循环的第一次迭代中找到第0个元素,之后不会出现错误,因为j = i - 1 = -1.永远不要在代码中编辑头部的数据.

所以你会有这个:

----------       -----       -----
| random |  ---> | 1 |  ---> | 2 |  ---> etc.
----------       -----       -----
  head            0th         1st

之后,在listGet函数中,你会对列表的制作方式产生误解.例如,当调用listGet(head, 0, &x)时,条件p->next != NULL && j < i将在第一次迭代时始终满足,这意味着返回的 node 不是第0个,而是头部.你应该写:

j = -1;  // 0 become -1
while(p->next != NULL && j < i)
{
    p = p->next;
    j++;
}

此外,还必须更改主循环的界限.实际上,listLength返回列表中的元素数(这里是10),但指数化不是从0开始的1 bt开始,这意味着您不能在10处停止(因为没有第10个 node ),而是在9处停止.因此,你必须写:

for(i = 0; i < ListLength(head) - 1; i++)
{
    if(ListGet(head, i, &x) == 0)      /* take out the element*/
    {
        printf("Error! \n");
        return 1;
    }
    else printf("%d    ", x);        /* show data elements*/
}

还有一点与此问题无关,但无论如何都必须纠正:销毁函数.

void Destroy(SLNode **head)
{
    SLNode *p, *p1;

    p = *head;
    while(p != NULL)
    {
        p1 = p;
        p = p->next;
        
        /* make NULL assignment here */
        p1->next = NULL;
        
        free(p1);
    }
    /* head has been already freed in the above loop
    *  do not try to manipulate it */
    // *head = NULL;
}

C++相关问答推荐

GCC:try 使用—WError或—pedantic using pragmas

需要大整数和浮点数.使用long long int和long double

如何在C宏中确定Windows主目录?

来自stdarg.h的c中的va_args无法正常工作<>

这是一个合法的C Strdup函数吗?

在C++中使用函数指针的正确语法

是否可以使用指针算法在不对齐的情况下在 struct 中相同类型的字段的连续序列之间移动?

C指针概念分段故障

C中的FREE函数正在触发断点

如何在C++中安全地进行浮点运算

这个空指针类型的转换是有效代码还是恶意代码?

使用ld将目标文件链接到C标准库

运行时错误:在索引数组时加载类型为';char';`的空指针

从C中的函数返回静态字符串是不是一种糟糕的做法?

区分MySQL C界面中的文本和BLOB字段

Linux Posix消息队列

C Makefile - 如何避免重复提及文件名

返回指向函数内声明的复合文字的指针是否安全,还是应该使用 malloc?

C 程序调用 malloc 导致总线错误?

从寄存器移动到频繁访问的变量时性能意外降低