C 中链表的问题

2023-12-11

我收到的提示要求使用 c 语言的程序来实现链接列表,并为用户提供在链接列表上执行不同功能的选项。需要的功能是:

  • isempty():检查列表是否为空并返回指示是否为空的值
  • add():向列表尾部添加一个元素
  • insert():在列表中的特定索引处插入元素
  • find():查找存储特定值的索引。 。如果函数失败,则返回一个值,表明
  • get():获取存储在特定索引处的值
  • remove():删除列表中第一次出现的特定值。如果函数失败,则返回一个值,表明
  • Replace():替换存储在特定索引处的值
  • delete():删除特定索引处的元素。 。如果函数失败,则返回一个值,表明
  • list():以 [a, b, c] 格式打印列表的元素

当我调用 add_tail 函数时,它允许我输入我想要添加的值,但大约一分钟后,我在终端中收到一条消息,说程序已被终止。可能是什么原因造成的?我还遇到了主函数中用于打印菜单并获取用户输入的 while 循环的问题。当我第一次运行程序时,菜单将正常打印,但是在完成操作后,菜单打印一次但跳过用户输入,然后再次打印但第二次接受用户输入。

头文件:

#ifndef LAB8_H_
#define LAB8_H_

#define FIND 'F'
#define EMPTY 'E'
#define ADD 'A'
#define INSERT 'I'
#define DELETE 'D'
#define REMOVE 'R'
#define REPLACE 'S'
#define GET 'G'
#define LIST 'L'
#define QUIT 'Q'
#define FAIL -100

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

struct node_t * create_node(int value);
struct node_t * add_tail(struct node_t * head, int value);
struct node_t * insert_node(struct node_t * head, int index, int value);
int is_empty(struct node_t * head);
int find_val(struct node_t * head, int value);
int get_value(struct node_t * head, int index);
struct node_t * replace_val(struct node_t * head, int index, int value);
struct node_t * remove_val(struct node_t * head, int value);
struct node_t * delete_node(struct node_t * head, int index);
void print_list(struct node_t * head);

#endif 

.c file:

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

struct node_t * create_node(int value)
{
        struct node_t * new_node = malloc(sizeof(struct node_t));
        new_node -> next = NULL;
        new_node -> value = value;

        return new_node;
}


struct node_t * add_tail(struct node_t * head, int value)
{
        struct node_t * tmp;

        if(head == NULL){
                printf("Cannot add tail to an empty list. Try again\n");
                return NULL;
        } else{
                while(head != NULL){
                        if(head -> next == NULL){
                                tmp = create_node(value);
                                head -> next = tmp;
                        } else{
                                head = head -> next;
                        }
                }
        }

        return head;
}


struct node_t * insert_node(struct node_t * head, int index, int value)
{
        struct node_t * tmp;
        struct node_t * new;

        if(index < 0){
                printf("Index cannot be a negative number. Please try again\n");
                return head;
        }

        if(index == 0){
                tmp = head;
                head = create_node(value);
                head -> next = tmp;
        } else {
                tmp = head;

                while(tmp != NULL){
                        if (index == 1){
                                struct node_t * prev = tmp;
                                tmp = tmp -> next;
                                new = create_node(value);
                                new -> next = tmp;
                                prev -> next = new;
                                head = prev;
                        } else if((tmp -> next == NULL) && (index != 0)){
                                printf("The index is not found in the bounds of the list. Try again\n");
                                return head;
                        } else{
                                tmp = tmp -> next;
                                index--;
                        }
                }
        }

        return head;
}

int is_empty(struct node_t * head)
{
        if(head == NULL){
                return 0;
        } else{
                return 1;
        }
}

int find_val(struct node_t * head, int value)
{
        int index = 0;

        if(head == NULL){
                printf("Cannot find value in empty list! Try again\n");
                index = -100;
        } else{
                while(head != NULL){
                        if((head -> next == NULL) && (head -> value != value)){
                                printf("The value does not exist in the list\n");
                                index = -100;
                        } else if(head -> value == value){
                                return index;
                        } else{
                                head = head -> next;
                                index++;
                        }
                }
        }

        return index;
}

int get_value(struct node_t * head, int index)
{
        int value;

        if(index < 0){
                printf("Index cannot be a negative number. Try again\n");
                value = -100;
        } else if(head == NULL){
                printf("Cannot find index in empty list. Try again\n");
                value = -100;
        } else{
                while(head != NULL){
                        if(index == 0){
                                value = head -> value;

                        } else if((head -> next == NULL) && (index != 0)){
                                printf("Index does not exist in the bounds of the list. Try again\n");
                                value= -100;
                        } else{
                                head = head -> next;
                                index--;
                        }
                }
        }

        return value;
}

struct node_t * replace_val(struct node_t * head, int index, int value)
{
        struct node_t * tmp;

        if(index < 0){
                printf("Index cannot be a negative number. Try again\n");
                return NULL;
        } else if(head == NULL){
                printf("Cannot replace elements in an empty list. Try again\n");
                return NULL;
        } else{
                while(head != NULL){
                        if (index == 0){
                                tmp = head;
                                tmp -> value = value;
                                free(head);
                                head = tmp;
                        } else if((head -> next == NULL) && (index != 0)){
                                printf("Index does not exist is the bounds of the list. Try again\n");
                                return NULL;
                        } else{
                                head = head -> next;
                                index--;
                        }
                }
        }

        return head;
}

struct node_t * remove_val(struct node_t * head, int value)
{
        struct node_t * tmp;

        if(head == NULL){
                printf("Value cannot be found in an empty list. Try again\n");
                return NULL;
        } else{
                while(head != NULL){
                        if((head -> next == NULL) && (head -> value != value)){
                                printf("The value does not exist in the list. Try again\n");
                                return NULL;
                        } else if(head -> next -> value == value){
                                tmp = head -> next;
                                head -> next = tmp -> next;
                                free(tmp);
                        } else{
                                head = head -> next;
                        }
                }
        }

        return head;
}

struct node_t * delete_node(struct node_t * head, int index)
{
        struct node_t * tmp;

        if(index < 0){
                printf("Index cannot be a negative number. Try again\n");
                return NULL;
        } else if(head == NULL){
                printf("Cannot delete elements from an empty list. Try again\n");
                return NULL;
        } else{
                while(head != NULL){
                        if((head -> next == NULL) && (index != 0)){
                                printf("The index is not found in the bounds of the list. Try again\n");
                                return NULL;
                        } else if(index == 1){
                                tmp = head;
                                head = head -> next;
                                tmp -> next = head -> next;
                                head -> next = NULL;
                                free(head);
                                head = tmp;
                        } else{
                                head = head -> next;
                                index--;
                        }
                }
        }

        return head;
}

void print_list(struct node_t * head)
{
        if (head == NULL){
                printf("The list is empty. Nothing to print\n");
        } else{
                while(head != NULL){
                        if(head -> next != NULL){
                                printf("%d, ", head -> value);
                        } else{
                                printf("%d", head -> value);
                        }

                        head = head -> next;
                }
        }
}

主文件:

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

int main(void)
{
        struct node_t * head = NULL;
        int index, value;
        char choice;
        int cont = 0;

        while(cont == 0){
                printf("Welcome to the Linked List operator. Here are the functions that can be performed:\n");
                printf("A) Add element to the end of the list\n");
                printf("I) Insert and element at a specific index\n");
                printf("E) Check if the list is empty\n");
                printf("F) Find a value in the list and return the index\n");
                printf("G) Get the value at a specific index\n");
                printf("S) Replace the value at a specific index\n");
                printf("R) Remove the first occurance of a specific value\n");
                printf("D) Delete the element at a specific index\n");
                printf("L) List all the elements currently stored\n");
                printf("Q) Quit the program\n");
                printf("Please enter which action you would like to perform: ");
                scanf("%c", &choice);

                switch(choice){
                        case ADD:
                                printf("Please enter the value you would like to add: ");
                                scanf("%d", &value);

                                head = add_tail(head, value);

                                break;
                        case INSERT:
                                printf("Please enter the index at which you want to insert a new element: ");
                                scanf("%d", &index);
                                printf("Please enter the value you would like to insert: ");
                                scanf("%d", &value);

                                head = insert_node(head, index, value);

                                break;
                        case EMPTY:
                                if(is_empty(head) == 0){
                                        printf("The list is empty!\n");
                                } else if(is_empty(head) == 1){
                                        printf("The list is not empty!\n");
                                } else{
                                        printf("Something went wrong\n");
                                }

                                break;
                        case FIND:
                                printf("Please enter the value that you would like to find in the list: ");
                                scanf("%d", &value);

                                index = find_val(head, value);

                                if(index == FAIL){
                                        printf("Error. Try again\n");
                                } else{
                                        printf("The index that the value %d exists at is %d\n", value, index);
                                }

                                break;
                        case GET:
                                printf("Please enter the index for which you would like to know the value: ");
                                scanf("%d", &index);

                                if(value == FAIL){
                                        printf("Error. Try again\n");
                                } else{
                                        printf("The value of the element at index %d is %d\n", index, value);
                                }

                                break;
                        case REPLACE:
                                printf("Please enter the index of the element that you would like to replace: ");
                                scanf("%d", &index);
                                printf("Please enter the new value: ");
                                scanf("%d", &value);

                                if(replace_val(head, index, value) == NULL){
                                        printf("Error. Could not replace node\n");
                                } else{
                                        printf("Success. Here is the new list:\n");
                                        print_list(head);
                                }

                                break;
                        case REMOVE:
                                printf("Please enter the value that you would like to remove the first occurance of: ");
                                scanf("%d", &value);

                                if(remove_val(head, value) == NULL){
                                        printf("Error. Could not remove node\n");
                                } else{
                                        printf("Success! Here is the new list:\n");
                                        print_list(head);
                                }

                                break;
                        case DELETE:
                                printf("Please enter the index of the element you would like to delete: ");
                                scanf("%d", &index);

                                if(delete_node(head, index) == NULL){
                                        printf("Error. Could not delete selected element\n");
                                } else{
                                        printf("Success! Here is the new list:\n");
                                        print_list(head);
                                }

                                break;
                        case LIST:
                                printf("[");
                                print_list(head);
                                printf("]\n");

                                break;
                        case QUIT:
                                printf("You have chosen to quit the program. Goodbye!\n");
                                cont = 1;

                                break;
                        default:
                                printf("You entered an invalid choice. Please try again. Goodbye!\n");
                }
        }

        return 0;
}

函数内的 if 语句add_tail

    if(head == NULL){
            printf("Cannot add tail to an empty list. Try again\n");
            return NULL;

没有意义。应该将其删除。

在函数的 while 循环中,指针head被改变了。

while(head != NULL){
        if(head -> next == NULL){
                tmp = create_node(value);
                head -> next = tmp;
        } else{
                head = head -> next;
        }
}

并且添加节点后循环不会中断。它将再次添加一个新节点。也就是说循环是无限的。

但即使你会插入break语句

while(head != NULL){
        if(head -> next == NULL){
                tmp = create_node(value);
                head -> next = tmp;
                break;
        } else{
                head = head -> next;
        }
}

函数返回的指针将不是指向链表头节点的指针。

该函数可以通过以下方式定义

struct node_t * add_tail( struct node_t *head, int value )
{
    struct node_t *new_node = create_node( value );

    if ( head == NULL )
    {
        head = new_node;
    }
    else
    {
        struct node_t *current = head;
        
        while ( current->next != NULL ) current = current->next;

        current->next = new_node;
    }

    return head;
}

我确信您的程序中的代码还存在其他问题。更新功能后您可以提出新问题add_tail你在这个问题中提到的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 中链表的问题 的相关文章

随机推荐

  • HTML5 使用 src 使用原始二进制数据

    假设我正在数据库中存储一个音频文件 稍后我想在我的应用程序中使用该 BLOB 或二进制文件
  • 如何访问 pybluez 中的蓝牙低级功能?

    是否有用于较低级别 bt 功能的 pybluez 包装函数 我在文档中找不到任何内容 我需要使用与以下功能等效的功能 l2ping single ping hcitool cc hcitool rssi hcitool lq hcitool
  • 不同窗口中两个文本框之间的数据绑定

    我创建了一个程序 在选中或取消选中复选框时更改文本框中的名称 我想在不同的窗口中复制这个文本框 我认为在 xaml 中使用数据挖掘是可能的 但名称仅出现在一个窗口中 第二个窗口窗口不接收数据 我向您展示了两个窗口的代码 你能帮助我吗 谢谢
  • IE 中的上标下划线

    由于时间有限 我的发言会很简短 所以如果没有我希望的那么详细 我深表歉意 我有一些代码 print a href Some text a
  • 从类路径目录获取资源列表

    我正在寻找一种方法来从给定的类路径目录中获取所有资源名称的列表 类似于方法List
  • Bootstrap 4 popper 未定义

    我正在尝试启动下拉菜单 每当我单击按钮时 我就会得到TypeError popper is undefined 我尝试导入捆绑包而不是bootstrap import bootstrap import bootstrap dist js b
  • 本地主机上的画架 JS 安全限制

    我正在学习 EaselJS 但遇到了这个奇怪的错误 无法从画布获取图像数据 因为画布已被跨源数据污染 easeljs 0 6 0 min js 71 未捕获 发生错误 这很可能是由于使用本地或跨域图像读取画布像素数据的安全限制 问题是 我的
  • 基于 ggplot 中百分位的颜色代码点

    我有一些非常大的文件 其中包含基因组位置 位置 和相应的群体遗传统计数据 值 我已成功绘制这些值 并希望对前 5 蓝色 和 1 红色 值进行颜色编码 我想知道在 R 中是否有一种简单的方法可以做到这一点 我已经尝试编写一个定义分位数的函数
  • PostgreSQL 上的透视行

    我有一个返回整行的查询 我需要将此结果转换到一个新表中 SELECT id no stud name group no class 1 class 2 class 3 class 4 FROM tbl stud class 这将返回以下内容
  • 通过 C# 中的反射获取“基本”数据类型,而不是奇怪的可空数据类型

    我的基本需求是从 LINQ to SQL 查询生成的匿名类型中获取数据类型 我有一段代码 比我能写的更聪明 因为我还没有真正深入研究反射 它从匿名类型返回数据类型 并且非常适合 linq2sql 属性中标记为 不可为空 的元素 因此 如果我
  • Spring Rest - 生成 Json 数据的异常[重复]

    这个问题在这里已经有答案了 我有一个值对象 我想通过 json Rest 调用公开它 我的项目中有许多其他的休息调用都工作得很好 但这个 1 由于某种原因不能 当我尝试返回该对象时 我收到一个我不知道如何解决的异常 值对象代码如下 减去访问
  • 如何将父 div 放置在其子 div 之上?

    我有一个容器 div 它有background color red 这个容器大约有 12 个孩子 最后一个孩子有background color blue 我试图将容器移到孩子的顶部background color blue 我为容器使用了
  • 如何在nodejs aws-sdk模块中设置多个aws凭证?

    我需要对 s3 SNS 等不同服务使用多个 AWS 凭证 var awsS3 require aws sdk var awsSes require aws sdk awsS3 config update region config awsR
  • 如何将 mysql 转储文件导入 Docker mysql 容器

    提前致以问候和感谢 我实际上是 docker 和 docker compose 的新手 迄今为止观看了大量视频并阅读了很多文章并进行了尝试 我有一个前端容器和一个后端容器 它们作为 Dockerfile 和 docker compose 设
  • 在 tableHeaderView 中使用自动布局

    我有一个UIView包含多行的子类UILabel 该视图使用自动布局 我想将此视图设置为tableHeaderView of a UITableView not节标题 该标题的高度将取决于标签的文本 而标签的文本又取决于设备的宽度 自动布局
  • Java 字节码签名

    作为我正在开发的编程语言的编译器的一部分 我在字节码中遇到了通用签名 我正在尝试将其解析并转换为 AST 解析算法大部分都有效 但似乎有一种特殊情况 其中这些签名的格式表现得有点奇怪 以下是其中一些案例 java util Arrays p
  • Spring MVC:即使存在所需的参数,文件上传也会出现错误请求(缺少参数)

    我有一个文件上传控制器 其方法如下所示 RequestMapping value upload method RequestMethod POST produces application json public ResponseBody
  • INDY 10 TCP 服务器 - 与非线程安全 VCL 代码结合

    VCL 不是线程安全的 因此我想在 INDY 10 TCP 中向 gui 写入信息不是一个好主意server execute 功能 如何将信息从服务器执行发送到VCL 我需要修改一个 TBitmap 里面tcpserver execute功
  • 模拟鼠标移动

    我的 UserControl 中有带有图像的 ListView 当我带来图片时 我会在从图像中移除鼠标时重新绘制图片 图片会滋养旧的 但是 当我第二次在同一张图片上绘制时 我不想重新绘制 但是当我拿走 ListView 的教堂时 navoz
  • C 中链表的问题

    我收到的提示要求使用 c 语言的程序来实现链接列表 并为用户提供在链接列表上执行不同功能的选项 需要的功能是 isempty 检查列表是否为空并返回指示是否为空的值 add 向列表尾部添加一个元素 insert 在列表中的特定索引处插入元素