1613551 发表于 2023-10-12 16:14:06

关于链表的问题

有没有大佬帮忙看看为什么无论插入的是多少,链表中总是会多出来一个8

#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElemType; // 把int替换成了Elemtype
typedef struct LinkList
{
    ElemType elem;                                        // 存储整形元素
    struct LinkList *next;                              // 指向直接后继元素的指针
} LinkList;                                             // 等同于用typedef把struct LinkList定义成Linklist就不需要再输入struct LinkList,可以直接输入LinkList
void InitList(LinkList *L);                               // 初始化链表声明
void CreateList(LinkList *L, ElemType a[], ElemType n);   // 创建链表声明
ElemType ListInsert(LinkList *L, ElemType i, ElemType e); // 链表插入声明
ElemType ListDelete(LinkList *L, ElemType i);             // 删除链表声明
void printlist(LinkList *headpoint);                      // 打印输出表中元素
ElemType main(void)
{
    LinkList head;                                                                                                   // 头结点
    LinkList *headpoint = &head;                                                                                       // 指向头结点的指针(结构体变量并不指向结构体,所以需要声明结构体指针)
    ElemType elements, n = 0, insertposition1, insertvalue1, insertposition2, insertvalue2, delete1, delete2; //
    InitList(headpoint);
    printf("##创建链表##\n\n");
    printf("请输入链表中元素值,以空格分隔(如,从键盘上依次输入21 18 30 75 42 56):");
    for (int i = 0; i < MaxSize; i++)
    {
      scanf("%d", &elements);
      n++;
      if (getchar() == '\n')
      {
            break;
      }
    }
    /*   putchar('\n');
    for (int i = 0; i < MaxSize; i++)
   {
         printf("%d ", elements);
   }
   putchar('\n');*/
    CreateList(headpoint, elements, n);
    printlist(headpoint); // 输出各元素的值
    putchar('\n');
    printf(
      "\n##插入操作##\n\n"
      "请输入第一次要插入的位置和插入的数值(插入位置和插入数值之间以空格相隔,如2 5,表示第2个位置插入数值5):");
    scanf("%d %d", &insertposition1, &insertvalue1);
    if (ListInsert(headpoint, insertposition1, insertvalue1))
    {
      printf("在第%d个位置插入%d成功\n", insertposition1, insertvalue1);
    }
    else
    {
      printf("在第%d个位置插入%d失败,插入位置不合法\n", insertposition1, insertvalue1);
    }
    printlist(headpoint);
    putchar('\n');
    printf(
      "请输入第二次要插入的位置和插入的数值(插入位置和插入数值之间以空格相隔,如2 5,表示第2个位置插入数值5):");
    scanf("%d %d", &insertposition2, &insertvalue2);
    if (ListInsert(headpoint, insertposition2, insertvalue2))
    {
      printf("在第%d个位置插入%d成功\n", insertposition2, insertvalue2);
    }
    else
    {
      printf("在第%d个位置插入%d失败,插入位置不合法\n", insertposition2, insertvalue2);
    }
    printlist(headpoint);
    putchar('\n');
    printf(
      "\n##删除操作##\n\n"
      "请输入第一次要删除元素的位置(如 2 表示删除第2个位置的数值):");
    scanf("%d", &delete1);
    if (ListDelete(headpoint, delete1))
    {
      printf("删除第%d个数据元素成功\n", delete1);
    }
    else
    {
      printf("删除第%d个数据元素失败,删除位置不合法\n", delete1);
    }
    printlist(headpoint);
    putchar('\n');
    printf(
      "请输入第二次要删除元素的位置(如 2 表示删除第2个位置的数值):");
    scanf("%d", &delete2);
    if (ListDelete(headpoint, delete2))
    {
      printf("删除第%d个数据元素成功\n", delete2);
    }
    else
    {
      printf("删除第%d个数据元素失败,删除位置不合法\n", delete2);
    }
    printlist(headpoint);
    putchar('\n');
    printf("\n=====顺序表初始化、插入,删除等操作已完成,程序结束!=====\n\n");
    system("pause");
    return 0;
}
void InitList(LinkList *L) /* 初始化链表 */
{
    L = (struct LinkList *)malloc(sizeof(struct LinkList *));
    L->next = NULL;
}
void CreateList(LinkList *L, ElemType a[], int n) /*创建链表 */
{
    LinkList *pre = L;
    int i;
    for (i = n - 1; i >= 0; i--)
    {
      LinkList *t = (struct LinkList *)malloc(sizeof(struct LinkList *));
      t->elem = a;
      t->next = NULL;
      pre->next = t;
      pre = pre->next;
    }
}
int ListInsert(LinkList *L, int i, ElemType e) /*按i位置插入元素*/
{

    int j = 0;
    LinkList *p = L;
    while (p && (j < i - 1))
    {
      p = p->next;
      j++;
    }
    if (!p || (j > i - 1))
      return 0;
    LinkList *t = (struct LinkList *)malloc(sizeof(struct LinkList *));
    t->elem = e;
    t->next = p->next;
    p->next = t;
    return 1;
}
int ListDelete(LinkList *L, int i) /*删除某个位置的元素*/
{
    int j = 0;
    LinkList *p = L;
    LinkList *del = NULL;
    while ((p->next) && (j < i - 1))
    {
      p = p->next;
      j++;
    }
    if (!(p->next) || (j > i - 1))
      return 0;
    del = p->next;
    p->next = del->next;

    free(del);
    return 1;
}
void printlist(LinkList *headpoint) // 打印输出表中元素
{
    printf("当前表中元素如下\n");
    LinkList *p = headpoint;
    while (p != NULL)
    {
      printf("%d ", p->elem);
      p = p->next;
    }
}

isdkz 发表于 2023-10-12 16:14:22

在函数InitList中,L = (struct LinkList *)malloc(sizeof(struct LinkList *)),这里应该是malloc(sizeof(struct LinkList)),因为sizeof(struct LinkList *)只是指针的大小,而不是整个结构体的大小。这个错误导致了头结点没有被正确初始化,所以在打印链表时会多出一个8。

正确的InitList函数应该是这样的:

void InitList(LinkList *L) /* 初始化链表 */
{
    L->next = NULL;
}

Mike_python小 发表于 2023-10-12 16:15:01

请问在您这里的链表中,哪一个地方会多出来一个8呢?是在链表长度的输出中还是在其他地方呢?

球一个最佳答案谢谢啦!这对我非常重要!{:10_254:}{:10_254:}{:10_254:}

1613551 发表于 2023-10-12 16:15:36

isdkz 发表于 2023-10-12 16:14
在函数InitList中,L = (struct LinkList *)malloc(sizeof(struct LinkList *)),这里应该是malloc(sizeof( ...

怎么做到秒回的

陶远航 发表于 2023-10-12 16:15:39

你的代码中存在一些问题,导致链表中总是会多出来一个8。问题主要出在你的初始化和创建链表的函数中。

在你的 InitList 函数中,你为 L 分配了内存,但是这个 L 是一个局部变量,它的改变并不会影响到函数外部的变量。所以,你在 main 函数中的 head 结构体并没有被正确初始化。

在你的 CreateList 函数中,你为新的节点分配内存时,使用了 sizeof(struct LinkList *),这实际上是分配了一个指针的大小,而不是一个 LinkList 结构体的大小。这可能会导致内存溢出,从而产生未定义的行为。

以下是修正后的代码:

#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElemType;

typedef struct LinkList {
    ElemType elem;
    struct LinkList *next;
} LinkList;

void InitList(LinkList **L);
void CreateList(LinkList *L, ElemType a[], int n);
int ListInsert(LinkList *L, int i, ElemType e);
int ListDelete(LinkList *L, int i);
void printlist(LinkList *headpoint);

int main(void) {
    // ...
    LinkList *headpoint;
    InitList(&headpoint);
    // ...
}

void InitList(LinkList **L) {
    *L = (LinkList *)malloc(sizeof(LinkList));
    (*L)->next = NULL;
}

void CreateList(LinkList *L, ElemType a[], int n) {
    LinkList *pre = L;
    for (int i = n - 1; i >= 0; i--) {
      LinkList *t = (LinkList *)malloc(sizeof(LinkList));
      t->elem = a[ i];
      t->next = NULL;
      pre->next = t;
      pre = pre->next;
    }
}

// ...


这样,你的 headpoint 就会被正确初始化,而且在创建链表时,每个节点都会被正确分配内存。
请注意,本回答来自GPT-4
如果问题已经解决,请设置最佳答案

1613551 发表于 2023-10-12 16:18:04

本帖最后由 1613551 于 2023-10-12 16:19 编辑

isdkz 发表于 2023-10-12 16:14
在函数InitList中,L = (struct LinkList *)malloc(sizeof(struct LinkList *)),这里应该是malloc(sizeof( ...

我试试

1613551 发表于 2023-10-12 16:19:39

isdkz 发表于 2023-10-12 16:14
在函数InitList中,L = (struct LinkList *)malloc(sizeof(struct LinkList *)),这里应该是malloc(sizeof( ...

不行,这样改的话还是会多一个8

1613551 发表于 2023-10-12 16:49:42

不行,chatgpt就是个垃圾玩意,一点也不智能。多了一个8是因为我把头结点的值也给打印出来了

Mike_python小 发表于 2023-10-12 19:03:41

1613551 发表于 2023-10-12 13:49
不行,chatgpt就是个垃圾玩意,一点也不智能。多了一个8是因为我把头结点的值也给打印出来了

{:10_256:}
页: [1]
查看完整版本: 关于链表的问题