【问题标题】:Appending nodes alphabetically to create linked list. Can't get nodes to link (C program)按字母顺序附加节点以创建链表。无法让节点链接(C 程序)
【发布时间】:2021-03-02 14:32:19
【问题描述】:

我的这部分代码有问题,出于某种原因,一切似乎都可以正常工作,但是当我打印出整个链表时,它只会打印标题和下一个节点,如果它通过“if (compare_node(list, node ) == -1)" 函数。我已经写了rest = list,但是我对rest 执行的操作似乎不会影响list 变量。我需要有关如何将剩余变量的输出链接到作为我的代码标题的列表变量的帮助。

link *add_node(link *list, link *node) { //  list = header, node =  new node I want to insert alphabetically
    link* temp;
    link* rest;
    rest = list;

    if (compare_node(list, node) == -1){
        temp = list;
        list = node;
        list->next = temp;
        printf("%s->%s->%s...\n",list->node_str, list->next->node_str, list->next->next->node_str);
        printf("nodes interchanged\n");
    }
    else{
        while(rest != NULL){
            if(compare_node(rest, node) == -1){
                printf("initial rest value: %s\n", rest->node_str);
                temp = rest;
                rest = node;
                rest->next = temp;
                printf("nodes interchanged, new rest value: %s\n", rest->node_str); //nodes interchanged: name
                printf("%s->%s->%s...\n",list->node_str, list->next->node_str, list->next->next->node_str);
                return list;
            }
            rest = rest->next;
            printf("next rest value: %s\n", rest->node_str); //next rest value: name
        }
        rest = node;
        printf("new rest value %s\n", rest->node_str);
    }
    return list;
}

我的输出如下所示:
输入用户 N1 的用户名:mike
输入用户 N2 的用户名:ann
安->麦克->(null)...
节点互换
输入用户 N3 的用户名:luka
下一个休息值:mike
初始休息值:麦克
节点互换,新的休息值:luka
安->麦克->(null)...
输入用户 N4 的用户名:nick
下一个休息值:mike
下一个剩余值:(null)
新的休息值尼克
输入用户 N5 的用户名:
1. ann
2. mike

我的整个代码如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STR_LEN 80

//STRUCT
typedef struct link_node
{
char node_str[MAX_STR_LEN];
struct link_node *next;
} link;

void Node_Create(link *Node, char* userName, link *nextNode);
int compare_node(link *n1, link *n2);
link *add_node(link *list, link *node);
void display_list(link *head);

//MAIN
int main() {
    int num, i = 1;
    char name[MAX_STR_LEN];
    link *Curr, *Head;

    printf("Enter the user name for user N%d: ", i);
    gets(name);
    Head = (link*)malloc(sizeof(link));
    Node_Create(Head, name, NULL);
    i++;

    while(1){
        printf("Enter the user name for user N%d: ", i);
        gets(name);
        if (strcmp(name, "\0") == 0) break;
        Curr = (link*)malloc(sizeof(link));
        Node_Create(Curr, name, NULL);
        Head = add_node(Head, Curr);
        i++;
    }

    display_list(Head);
    printf("\n%s\n", Head->node_str);

    return 0;
}

//FUNCTION FOR CREATING NODES
void Node_Create(link *Node, char* userName, link *nextNode) {
    strcpy(Node->node_str, userName);
    Node->next = nextNode;
}

//FUNCTION FOR COMPARING NODES
int compare_node(link *n1, link *n2) {
    link* Temp;

    if(n1->node_str[0] > n2->node_str[0])
        return -1;
    else if(n1->node_str[0] == n2->node_str[0])
        return 0;
    else
        return 1;
}

//FUNCTION FOR ADDING NODES
link *add_node(link *list, link *node) { //  list = header, node =  new node I want to insert alphabetically
    link* temp;
    link* rest;
    rest = list;

    if (compare_node(list, node) == -1){
        temp = list;
        list = node;
        list->next = temp;
        printf("%s->%s->%s...\n",list->node_str, list->next->node_str, list->next->next->node_str);
        printf("nodes interchanged\n");
    }
    else{
        while(rest != NULL){
            if(compare_node(rest, node) == -1){
                printf("initial rest value: %s\n", rest->node_str);
                temp = rest;
                rest = node;
                rest->next = temp;
                printf("nodes interchanged, new rest value: %s\n", rest->node_str); //nodes interchanged: name
                printf("%s->%s->%s...\n",list->node_str, list->next->node_str, list->next->next->node_str);
                return list;
            }
            rest = rest->next;
            printf("next rest value: %s\n", rest->node_str); //next rest value: name
        }
        rest = node;
        printf("new rest value %s\n", rest->node_str);
    }
    return list;
}

//FUNCTION FOR DISPLAYING NODES
void display_list(link *head) {
    link *rest = head;
    int i = 1;

    while(rest != NULL){
        printf("%d. %s\n", i++, rest->node_str);
        rest = rest->next;
    }
}

提前致谢:)

【问题讨论】:

  • 关于:gets(name); 函数:gets() 已经贬值多年,大约十年前从 C 语言中完全删除。强烈建议使用fgets()(与gets() 有不同的参数列表)
  • Singly Linked List (node only, no wrapper) 中查看addinorder()。对于字符串,您可以将while (ps &amp;&amp; ps-&gt;data &lt;= pn-&gt;data) 替换为while (ps &amp;&amp; strcmp (ps-&gt;data, pn-&gt;data) &lt; 0)。更重要的是见Why gets() is so dangerous it should never be used!。改用fgets (name, MAX_STR_LEN, stdin) 并用name[strcspn (name, "\n")] = 0; 从末尾修剪'\n'
  • 编译时,始终启用警告,然后修复这些警告。
  • 谢谢,我会这样做,但我认为这不是它无法正常工作的原因。 @DavidC.Rankin
  • 是的,这也可以,它只是意味着具有相同第一个字符的两个字符串不会被严格排序。从效率的角度来看,调用strcmp() 基本上做同样的事情,并在它到达第一个不同的字符时停止 - 或字符串的结尾,所以从优化的角度来看,第一个字符的技巧并没有多大作用。

标签: c loops linked-list


【解决方案1】:

要替换前一个节点,您必须保留一个指向它的指针。例如,您可以这样做:

    link * prev = NULL; 
    while(rest != NULL){
        if(compare_node(rest, node) == -1){
            temp = rest;
            rest = node;
            rest->next = temp;
            if (prev) prev->next = rest; //<==== Sets the next of previous
            return list;
        }
        prev = rest; // <=== Stores previous
        rest = rest->next;
        printf("next rest value: %s\n", rest->node_str); //next rest value: name
    }
    rest = node;
    printf("new rest value %s\n", rest->node_str);

当头部改变时,你不需要这样做,因为根据定义,头部之前没有节点。

【讨论】:

  • 谢谢你,这解释了它。我为我的代码苦苦挣扎了很长时间,我认为你刚刚解决了它。
【解决方案2】:

前 2 条评论。正如您在 cmets 中已经被告知的那样,不要使用 gets,而使用 strcmp 来比较字符串(您的版本只比较两个字符串的第一个字符)。

现在解决实际问题:

要在链表中插入节点,必须更改前一个节点的链接。假设我们的字典顺序是 B B -> C -> D。你的测试会说:

  • X > A:下一个尝试
  • X > B:下一个尝试
  • x

但你必须这样做:

B->next = X;
X->next = C;

改变任何其他变量的值是没有用的,这意味着你必须记录上一个节点。

【讨论】:

  • 谢谢解释,但我想知道,如何记录上一个节点?特别是在头部变量被替换的情况下?
  • 另外,rest 用“list”初始化。我有“休息=列表;”写在“link* rest;”之后
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 2014-03-12
  • 1970-01-01
  • 1970-01-01
  • 2021-01-01
相关资源
最近更新 更多