简体   繁体   English

这个单链表程序有什么问题?

[英]What's the problem in this program of Single Linked list?

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

     struct node {
        int data;
    struct node* nextptr;
     } * manode;

    void add();
    void delete ();
    void display();

    int main()
    {
    int choice;

    int echoice;
    while (choice != 4) {
        printf("\n \t ENTER YOUR CHOICE FOR SINGLE LINKED LIST ");
        printf("\n \t 1. ADD ELEMENT ");
        printf("\n \t 2. DISPLAY ELEMENT ");
        printf("\n \t 3. DELETE ELEMENT ");
        printf("\n \t 4. EXIT  ");
        scanf("%d", &choice);
        switch (choice) {
        case 1:
            while (echoice != 0) {
                add();
                printf("\n DO YOU WANT TO CONTINUE 1/0 ");
                scanf("%d", &echoice);
            }
            break;
        case 2:
            display();
            break;
        case 3:
            delete ();
            break;
        case 4:
            exit(0);
            break;
        default:
            printf("\n \t WRONG VALUE ENTERED ");
        };
    }
    return 0;
}


#Add function is responsible to add the first node and all the remaining nodes as well.



    void add()
{
    struct node *tmp, *tmp2;
    tmp = malloc(sizeof(struct node));
    tmp2 = malloc(sizeof(struct node));
    int value;

    printf("    ENTER THE VALUE YOU WANT TO ENTER   ");
    scanf("%d", &value);

    if (manode == NULL) {
        manode = malloc(sizeof(struct node));
        printf("  FIRST ENTRY ");
        manode->data = value;
        manode->nextptr = NULL;
        tmp = manode;
        printf("THE DATA %d  ", manode->data);
    }


    else {
        if (tmp2 == NULL) {
            printf("\n MEMORY ALLOCATION FAILED");
        }
        else {
            tmp2->data = value;
            tmp2->nextptr = NULL;
            tmp->nextptr = tmp2;
            tmp = tmp->nextptr;
        }
    }
    //manode=tmp;
}

void display()
{
    struct node* tmp1;
    if (manode == NULL) {
        printf(" MEMORY ALLOCATION FAILED ");
    }
    else {
        tmp1 = manode;
        while (tmp1 != NULL) {
            printf("\n%d  DATA IS DISPLAY \n", tmp1->data);
            tmp1 = tmp1->nextptr;
        }
    }
}

void delete ()
{
    struct node* tmp;
    if (manode == NULL) {
        printf("NOTHING TO DELETE ");
    }
    else {
        tmp = malloc(sizeof(struct node));
    }
}

Kindly copy and compile the code, it's working but it doesn't display the contents in the list.请复制并编译代码,它正在工作,但它不显示列表中的内容。 Kindly copy and compile the code, it's working but it doesn't display the contents in the list.Kindly copy and compile the code, it's working but it doesn't display the contents in the list.Kindly copy and compile the code, it's working but it doesn't display the contents in the list.请复制并编译代码,它可以工作但它不显示列表中的内容。请复制并编译代码,它可以工作但它不显示列表中的内容。请复制并编译代码,它是工作,但它不显示列表中的内容。

As I see, there are a number of issues with your code.如我所见,您的代码存在许多问题。

  • do not use conio.h .不要使用conio.h This thing is from the '80s and adds nothing to a modern program but problems这东西是 80 年代的东西,对现代程序没有任何帮助,但问题
  • never try to implement an ADT --- any container such as list, set, map --- as a node.永远不要尝试实现 ADT --- 任何容器,如列表、集合、map --- 作为节点。 It will only give you trouble: a list is a collection of nodes.它只会给您带来麻烦:列表是节点的集合。 Each node has a payload, some data.每个节点都有一个有效负载,一些数据。 This data can have a key, something used to compare records.该数据可以有一个键,用于比较记录。 A node is not a list.节点不是列表。 A node is not the data.节点不是数据。 A list is not a node.列表不是节点。 As seen from the list, the data are the nodes.从列表中可以看出,数据是节点。 This way you can use anything as data in your list.这样,您可以将任何内容用作列表中的数据。 And this is the purpose of a container: write once, use always.这就是容器的目的:一次编写,始终使用。 And the list has metadata, some obvious controls such its size, starting addres, ending address and possibly other stuff.该列表具有元数据,一些明显的控制,例如其大小,起始地址,结束地址以及可能的其他内容。
  • do not use void() .不要使用void() Is a waste, sometimes an error.是浪费,有时是错误。 In your case is an error.在你的情况下是一个错误。 All pointers are buried inside the functions and die there.所有指针都埋在函数内部并死在那里。 So display() and add() does not work所以display()add()不起作用
  • do not typedef pointers.不要typedef指针。 It is a mess.这是一团糟。 In you case manode is a pointer.在您的情况下manode是一个指针。 How are someone, even yourself a few days from now, remember what is what?几天后的某个人,甚至是你自己,还记得什么是什么吗? If manode is a typedef for a struct everyone knows that如果manode是一个结构的 typedef,每个人都知道
         manode* many_nodes[30]

declare many_nodes as a pointer to an array of structs. many_nodes声明为指向结构数组的指针。 The asterisk tells everything: many_nodes is a pointer to manode .星号说明了一切: many_nodes是指向manode的指针。 BTOS if you bury the * inside the typedef you will always need to refer to the code in the header. BTOS 如果您将*埋在 typedef 中,您将始终需要参考 header 中的代码。

  • do not mix code of the list with I/O.不要将列表的代码与 I/O 混合。 It will only make your like harder.它只会让你的喜欢更难。 You have a list of simple int , so declare add() for instance as int add(int item, List* the_list) .您有一个简单的int列表,因此例如add()声明为int add(int item, List* the_list) This way is more readable and you can write a simple loop to fill the list with a few hundred or just one node and start testing.这种方式更具可读性,您可以编写一个简单的循环来用几百个或仅一个节点填充列表并开始测试。
  • if you have a menu just write it as a function that returns the user option.如果您有菜单,只需将其写为返回用户选项的 function。 But add it later to the program.但稍后将其添加到程序中。 A menu serves nothing to the list and to the program菜单对列表和程序没有任何作用
  • scanf() was not written to read input from the keyboard. scanf()没有被写入从键盘读取输入。 It is for scan formatted input, hence the name.它用于扫描格式的输入,因此得名。 It will always give you trouble when reading from stdin.从标准输入读取时,它总是会给您带来麻烦。 But do your part and at least always test the return of scanf().但是尽你的一份力量,至少总是测试 scanf() 的返回。 ALWAYS.总是。 rtfm. rtfm。
  • do not write \n \t on a printf.不要在 printf 上写\n \t Use just tabs or count the spaces.仅使用制表符或计算空格。
  • always initialize all variables.总是初始化所有变量。 In your code you start testing choice and echoice with no value set.在您的代码中,您开始测试没有设置值的choiceechoice
  • what is the point of having a loop on option 1, add since anyway the user will need to input an answer and enter 1 ?在选项 1 上有一个循环有什么意义,添加因为无论如何用户都需要输入答案并输入1

Back to your program返回您的程序

See below your code rearranged using some of the things I wrote above.请参阅下面的代码,使用我上面写的一些东西重新排列。 Compare with your code与您的代码进行比较

Sample Code示例代码

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

typedef struct st_node
{
    int data;
    struct st_node* nextptr;

}   Node;

typedef struct tlist
{
    unsigned    size;
    Node*       start;

}   List;


int     add(int, List*);
int     delete (int, List*);
int     display(List*);
int     menu();

int         main(void)
{
    List one;
    one.size = 0;
    one.start = NULL;

    int res = menu();
    printf("menu returned %d\n", res);

    display(&one);
    for( int i = 0; i<10; i+=1)
        add(i,&one);
    display(&one);
    return 0;
}

int         add(int value, List* l)
{
    if ( l == NULL ) return -1;
    Node* node = (Node*) malloc(sizeof(Node));
    // simplest: insert at the beginning
    node->nextptr = l->start;
    node->data = value;
    l->start = node;
    l->size += 1;
    return l->size;
};

int         display(List* l)
{
    if ( l== NULL) return -1;
    if ( l->size == 0 )
    {
        printf("\n\tlist is empty\n\n");
        return 0;
    }
    else
    {
        printf("\n\t%d elements in the list\n\n", l->size);
    };

    Node* p = l->start;
    for( unsigned i = 0; i< l->size; i+=1)
    {
        printf("%3d: %11d\n", 1+i, p->data);
        p = p->nextptr;
    };
    return l->size;
}

int delete (int v, List* l)
{
    return 0;
}

int         menu()
{
    int choice = 0;
    int res = 0;
    printf(
        "\n\tENTER YOUR CHOICE FOR SINGLE LINKED LIST:\n\
\n\t\t1. ADD ELEMENT\
\n\t\t2. DISPLAY ELEMENT\
\n\t\t3. DELETE ELEMENT\
\n\t\t4. EXIT\
\n\n\t\tYour choice:   ");

   while( res != 1 )
   {
        res = scanf("%d", &choice);
        if ( choice >=1 && choice <= 4 ) return choice;
   };
   return 4;
}

OUTPUT OUTPUT

        ENTER YOUR CHOICE FOR SINGLE LINKED LIST:

                1. ADD ELEMENT
                2. DISPLAY ELEMENT
                3. DELETE ELEMENT
                4. EXIT

                Your choice:   2
menu returned 2

        list is empty


        10 elements in the list

  1:           9
  2:           8
  3:           7
  4:           6
  5:           5
  6:           4
  7:           3
  8:           2
  9:           1
 10:           0

And it is just an example of stuff using a more manageable list.这只是使用更易于管理的列表的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM