首页 > 解决方案 > 将新工作人员添加到列表中,但保持按名称排序

问题描述

我必须在工人列表中添加一个新工人,但我必须按字母顺序将它放在正确的位置。

我为新名称提供了几个选项:

  1. 列表是空的,所以我只是将新名称放入列表中
  2. 列表中有 1 名工人
  3. 新名称 < 现有名称
  4. 新名称比前一个大,但比下一个小
  5. 新名字大于姓氏

我哪里做错了 ?

//first function-add a new worker to the list//
Worker * addWorker(Worker *head, char name[], char *city, int id, float 
salary)
{
Worker *new = (Worker *)malloc(sizeof(Worker));
strcpy(new->name, name);
new->city = city;
new->id = id;
new->salary = salary;
if (head == NULL)  //checks if the list is empty//
{
    new->next = NULL;
    head = new;
    return head;
}
if (length(head) == 1) //checks if the list has 1 person only //
{
    if (head->name < new->name)
    {
        head->next = new;
        new->next = NULL;
        return head;
    }
    if (head->name > new->name)
    {
        new->next = head;
        return new;
    }
}
Worker *x = head;
Worker *y = head->next;
while (x != NULL)
{
    if (x->name > new->name) //checks if the name needs to be first in 
the list//
    {
        new->next = x;
        return new;
    }
    if ((x->name < new->name) && (y->name > new->name)) // checks if the 
name needs to be somewhere in the middle of the list//
    {
        x->next = new;
        new->next = y;
        return head;
    }

    if ((x->name < new->name) && (y==NULL)) //checks if the name needs to 
be last in the list//
    {
        x->next = new;
        new->next = NULL;
        return head;
    }
    x = x->next;
    y = y->next;
}

return head;

}

标签: clist

解决方案


抱歉,您的代码太复杂了,我不想尝试理解它

如果addWorker返回新的工人(而不是列表的新头),第一个参数必须是头被记忆的位置,所以 a Worker ** head. 在您只需要在列表上迭代到正确的位置以插入新工作人员之后。

要比较字符串,请使用strcmp

一个解决方案是:

//first function-add a new worker to the list//
Worker * addWorker(Worker ** head, char name[], char *city, int id, float salary)
{
  Worker * new = malloc(sizeof(Worker));

  strcpy(new->name, name); /* hope the name is not too long to be saved in Worker */
  new->city = city; /* hope the city is always a valid string */
  new->id = id;
  new->salary = salary;

  while ((*head) && (strcmp(name, (*head)->name) > 0))
    head = &(*head)->next;

  new->next = *head;
  *head = new;

  return new;
}

请注意,对于城市和名称没有相同的行为是很奇怪的,但我尊重这一点。


如果我有一些定义来拥有一个完整的程序,包括打印和删除:

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

typedef struct Worker {
  char name[10];
  const char * city;
  int id;
  float salary;
  struct Worker * next;
} Worker;

//first function-add a new worker to the list//
Worker * addWorker(Worker ** head, char name[], char *city, int id, float salary)
{
  Worker * new = (Worker *)malloc(sizeof(Worker));

  strcpy(new->name, name); /* hope the name is not too long to be saved in Worker */
  new->city =  city; /* hope the city is always a valid string */
  new->id = id;
  new->salary = salary;

  while ((*head) && (strcmp(name, (*head)->name) > 0))
    head = &(*head)->next;

  new->next = *head;
  *head = new;

  return new;
}

void pr(Worker * l)
{
  while (l != NULL) {
    printf("%s %s %d %f\n", l->name, l->city, l->id, l->salary);
    l = l->next;
  }
}

void del(Worker * l)
{

  while (l != NULL) {
    Worker * w = l;

    l = l->next;
    free(w);
  }
}

int main()
{
  Worker * l = NULL;

  addWorker(&l, "aze", "c1", 1, 1);
  addWorker(&l, "qsd", "c2", 2, 2);
  addWorker(&l, "aaa", "c3", 3, 3);
  addWorker(&l, "wxc", "c4", 4, 4);

  pr(l);

  del(l);
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra -Wall w.c
pi@raspberrypi:/tmp $ ./a.out
aaa c3 3 3.000000
aze c1 1 1.000000
qsd c2 2 2.000000
wxc c4 4 4.000000

在valgrind下执行:

pi@raspberrypi:/tmp $ valgrind ./a.out
==17053== Memcheck, a memory error detector
==17053== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==17053== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==17053== Command: ./a.out
==17053== 
aaa c3 3 3.000000
aze c1 1 1.000000
qsd c2 2 2.000000
wxc c4 4 4.000000
==17053== 
==17053== HEAP SUMMARY:
==17053==     in use at exit: 0 bytes in 0 blocks
==17053==   total heap usage: 5 allocs, 5 frees, 1,136 bytes allocated
==17053== 
==17053== All heap blocks were freed -- no leaks are possible
==17053== 
==17053== For counts of detected and suppressed errors, rerun with: -v
==17053== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

第二个建议,如果addWorker返回列表的新头部而不是新的工作人员,addWorkermain的新定义

Worker * addWorker(Worker * head, char name[], char *city, int id, float salary)
{
  Worker ** phead = &head;
  Worker * new = (Worker *)malloc(sizeof(Worker));

  strcpy(new->name, name); /* hope the name is not too long to be saved in Worker */
  new->city =  city; /* hope the city is always a valid string */
  new->id = id;
  new->salary = salary;

  while ((*phead) && (strcmp(name, (*phead)->name) > 0))
    phead = &(*phead)->next;

  new->next = *phead;
  *phead = new;

  return (new->next == head) ? new : head;
}

int main()
{
  Worker * l = NULL;

  l = addWorker(l, "aze", "c1", 1, 1);
  l = addWorker(l, "qsd", "c2", 2, 2);
  l = addWorker(l, "aaa", "c3", 3, 3);
  l = addWorker(l, "wxc", "c4", 4, 4);

  pr(l);

  del(l);
}

推荐阅读