c有序链表逻辑错误

时间:2014-04-07 23:40:49

标签: c linked-list

我正在编写一个维护有序链表的程序。我遇到的问题是,当我使用显示列表中所有内容的函数时,只显示最后一个条目。我想帮助您找出逻辑错误的位置。

例如,如果我使用insert方法输入以下键和数据

1 "test"
2 "more tests"

然后我使用dumplist函数,这是输出:
2 "more tests"

这是主程序

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "list_funcs.h"

int main(void) {

    struct data_node *first=NULL, *new_node, *ptr;
    char input = 't';


    do {    
            int tempKey;
            char s[25];
            printf("Enter list command (+-flx):  ");
            scanf("%c", &input);
            printf("%c detected", input); 
            //insterting data into the list
            if (input=='+') {
                printf(" \n Enter key data :  ");
                scanf("%d", &tempKey);
                printf("\n %d detected ", tempKey); 
                printf("\n Enter the string to be stored:  ");
                scanf("%s", s);
                printf("\n You entered %s  ", s); 
                ptr=insert(&first, tempKey);
                first = ptr;
                strcpy(ptr->name, s);

            }
            //finding in the list
            if (input == 'f') {
                printf("\n Enter key data :  ");
                scanf("%d", &tempKey);
                printf("\n %d detected ", tempKey);
                ptr=find_node(first, tempKey);
                dump_node(ptr);

            }
            //printing list
            if (input == 'l') {
                dump_list(first);               

            }
            //deletion
            if (input == '-') {
                printf("Enter key data :  ");
                scanf("%d", &tempKey);
                printf(" \n  %d detected ", tempKey);
                delete(&first, tempKey);
            }

    } while (input!='x');
    printf("Goodbye the program has ended!");



return 0;

}

这是函数

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "list_funcs.h"
struct data_node * insert (struct data_node **p_first, int elem) {


    struct data_node *new_node, *prev, *current;
    current=*p_first;
    while (current != NULL && elem > current->data) {
        prev=current;
        current=current->next;
    } /* end while */
/* current now points to position *before* which we need to insert */
    new_node = (struct data_node *) malloc(sizeof(struct data_node));
    new_node->data=elem;

    new_node->next=current;
    if ( current == *p_first ) /* insert before 1st element */
        *p_first=new_node; 
    else                       /* now insert before current */
        prev->next=new_node;
/* end if current == *p_first */
    return new_node;
};

struct data_node * find_node (struct data_node *p, int elem) {
while (p != NULL) {
   if ( elem == p->data )
      return p;
   p=p->next;
   } /* end while */
}; /* end find_node */

void dump_node (struct data_node *current) {
printf("Dumping node: ");
if (current != NULL)
   printf("%s: %d\n", current->name, current->data);
}; /* end dump_list */


void dump_list (struct data_node *current) {
    printf("List dump:\n");
    while (current != NULL) {
        printf("%s: %d\n", current->name, current->data);
        current=current->next;
    } /* end while */
    printf("\n");
}; /* end dump_list */

int delete (struct data_node **p_first, int elem) {
    int retval = 0;
    struct data_node *current, *prev;
    current=*p_first;
    while (current != NULL && elem != current->data ) {
        prev=current;
        current=current->next;
   }
    if (current == NULL) /* element not found */
        return retval;
/* current now points to node to delete */
    if ( current == *p_first ) /* delete 1st node */
        *p_first = (*p_first)->next;
    else  /* link previous to next thus skipping over node to delete */
        prev->next=current->next;
        free(current);
        retval=1;
    return retval;
}; /* end delete */

编辑添加头文件

#define STRINGMAX 25

struct data_node {
  char name [STRINGMAX];
  int data;
  struct data_node *next;
  };



struct data_node * insert (struct data_node **, int);
struct data_node * find_node (struct data_node *, int);
void dump_list (struct data_node *); 
int delete (struct data_node **, int);
void dump_node (struct data_node *);

1 个答案:

答案 0 :(得分:0)

你的问题在这里:

printf("\n You entered %s  ", s); 
ptr=insert(&first, tempKey);
first = ptr;

您的函数已仔细更新first以指向列表的头部,但您随后使用新插入的密钥覆盖它。如果以相反的顺序输入数据,一切都很好。如果你是按照前进顺序进行的,那么你就不会丢掉列表的头部。

删除作业: first = ptr;

此外,您的insert函数应作为参数传递s,并应将其复制到ptr->name

工作代码

//#include "list_funcs.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef LIST_FUNCS_H_INCLUDED
#define LIST_FUNCS_H_INCLUDED

#define STRINGMAX 25

struct data_node
{
    char name[STRINGMAX];
    int data;
    struct data_node *next;
};

struct data_node *insert(struct data_node **, int, char *);
struct data_node *find_node(struct data_node *, int);
void dump_list(struct data_node *);
int delete(struct data_node **, int);
void dump_node(struct data_node *);

#endif

int main(void)
{
    struct data_node *first = NULL, *ptr;
    char input = 't';

    do
    {
        int tempKey;
        char s[STRINGMAX];
        printf("Enter list command (+-flx):  ");
        scanf(" %c", &input);
        printf("%c detected\n", input);

        if (input == '+')
        {
            printf(" \n Enter key data :  ");
            scanf("%d", &tempKey);
            printf("\n %d detected ", tempKey);
            printf("\n Enter the string to be stored:  ");
            scanf("%s", s);
            printf("\n You entered [%s]\n", s);
            ptr = insert(&first, tempKey, s);
            //first = ptr;
        }
        else if (input == 'f')
        {
            printf("\n Enter key data :  ");
            scanf("%d", &tempKey);
            printf("\n %d detected\n", tempKey);
            ptr = find_node(first, tempKey);
            dump_node(ptr);
        }
        else if (input == 'l')
        {
            dump_list(first);
        }
        else if (input == '-')
        {
            printf("Enter key data :  ");
            scanf("%d", &tempKey);
            printf(" \n  %d detected ", tempKey);
            delete(&first, tempKey);
        }
    } while (input != 'x');

    printf("Goodbye the program has ended!\n");
    return 0;
}

struct data_node *insert(struct data_node **p_first, int elem, char *str)
{
    struct data_node *new_node, *prev = 0, *current;
    current = *p_first;
    while (current != NULL && elem > current->data)
    {
        prev = current;
        current = current->next;
    }
    dump_node(current);
    dump_node(prev);

    new_node = (struct data_node *) malloc(sizeof(struct data_node));
    new_node->data = elem;
    strcpy(new_node->name, str);
    new_node->next = current;

    if (current == *p_first)
        *p_first = new_node;
    else
        prev->next = new_node;

    dump_node(*p_first);
    dump_node(new_node);
    return new_node;
}

struct data_node *find_node(struct data_node *p, int elem)
{
    while (p != NULL)
    {
        if (elem == p->data)
            return p;
        p = p->next;
    }
    return p;
}

void dump_node(struct data_node *current)
{
    printf("Dumping node %p: ", (void *)current);
    if (current != NULL)
        printf("%s: %d (%p)", current->name, current->data, current->next);
    putchar('\n');
}

void dump_list(struct data_node *current)
{
    printf("List dump:\n");
    while (current != NULL)
    {
        printf("%s: %d\n", current->name, current->data);
        current = current->next;
    }
    printf("\n");
}

int delete(struct data_node **p_first, int elem)
{
    int retval = 0;
    struct data_node *current, *prev;
    current = *p_first;
    while (current != NULL && elem != current->data)
    {
        prev = current;
        current = current->next;
    }
    if (current == NULL)
        return retval;

    if (current == *p_first)
        *p_first = (*p_first)->next;
    else
        prev->next = current->next;
    free(current);
    retval = 1;
    return retval;
}

(我没有测试删除;查找和列表功能正常,但现在打印的信息比以前更多。)