C程序排序链表

C程序排序链表,c,sorting,linked-list,strcmp,C,Sorting,Linked List,Strcmp,这个程序应该创建一个排序列表,并按名字和姓氏对每个用户进行排序。我似乎不知道如何正确地把名字分类 我只对append_to_list函数有一个问题,其余函数工作正常 当我第一次开始输入姓名时: user ID: Last Name: First Name: 3 Alex Alex 2 Jones Alex 1 andrew john 它的排序很好

这个程序应该创建一个排序列表,并按名字和姓氏对每个用户进行排序。我似乎不知道如何正确地把名字分类

我只对append_to_list函数有一个问题,其余函数工作正常

当我第一次开始输入姓名时:

user ID:    Last Name:    First Name:
3                Alex          Alex
2                Jones         Alex
1                andrew        john
它的排序很好,直到我输入一个应该在两个名称之间排序的名称 当我输入Andrew,Alex的名字时,就会发生这种情况

 user ID:    Last Name:    First Name:
 4                Andrew        Alex
 3                Alex          Alex
 2                Jones         Alex
 1                andrew        john
但是Andrew Alex应该在用户2和3之间


#包括
#包括
#包括
#包括“user.h”
#包括“readline.h”
//函数append_to_list从user、id、name获取用户输入,并将其放在列表的末尾
//以及按字母顺序对每个名称进行排序
结构用户*将\附加到\列表(结构用户*族)
{
结构用户*cur、*prev、*new_节点;
//生成内存
new_node=malloc(sizeof(struct user));
如果(new_node==NULL){
printf(“malloc在append中失败\n”);
回归家庭;
}
printf(“输入用户ID:\n”);
scanf(“%d”和新节点->编号);
printf(“输入用户名:\n”);
读取行(新建节点->姓氏、姓名);
printf(“输入用户名:\n”);
读取行(新建节点->第一个名称、名称);
对于(cur=family;cur!=NULL;cur=cur->next){
如果(新节点->编号==当前->编号){
printf(“用户已存在:%s,%s\n”,新节点->名字,新节点->姓氏);
空闲(新的_节点);
回归家庭;
}   
}       
对于(cur=family,prev=NULL;cur!=NULL
&&(strcmp(新节点->第一个名称,cur->第一个名称)<0)
&&(strcmp(新节点->姓氏,cur->姓氏)<0);
prev=cur,cur=cur->next){
如果((strcmp(新节点->姓氏,cur->姓氏)<0))中断;
if((strcmp(新节点->第一个名称,cur->第一个名称)==0))
如果((strcmp(新节点->第一个名称,cur->第一个名称)<0))中断;
;
}
//使用strcmp==0查看名称是否已存在
if(cur!=NULL&(strcmp(新节点->第一个名称,cur->第一个名称)==0)
&&(strcmp(新节点->姓氏,cur->姓氏))==0)
{
printf(“用户已存在:%s,%s\n”,新节点->名字,新节点->姓氏);
空闲(新的_节点);
回归家庭;
}
//将linkedlist追加到末尾
新建节点->下一步=当前;
//检查节点是否为空
if(prev==NULL){
返回新的_节点;
}否则{
上一步->下一步=新建节点->下一步;
回归家庭;
}
}
//函数delete_from_list可从族中删除用户
结构用户*从列表中删除(结构用户*族)
{
结构用户*prev,*cur;
int-id;
int not_found=0;
printf(“输入用户ID:\n”);
scanf(“%d”和&id);
对于(cur=family,prev=NULL;cur!=NULL;prev=cur,cur=cur->next){
如果(id==cur->number){
//如果族上只有一个用户
if(prev==NULL){
family=cur->next;
如果用户处于家庭中间
//将上一个节点连接到当前节点
}否则{
上一步->下一步=当前->下一步;
}
printf(“用户已删除:%s,%s\n”,cur->first\u name,cur->last\u name);
免费(cur);
}
其他的
未找到=1;
}
如果(未找到==1){
printf(“未找到用户\n”);
}
回归家庭;
}   
//函数find_user按ID搜索族,并将其与用户名匹配
无效查找用户(结构用户*族)
{
结构用户*p=家庭;
int-id;
整数计数=0;
printf(“输入用户ID:\n”);
scanf(“%d”和&id);
//将族与用户输入的ID进行比较
//如果ID与设置为1的计数相同
如果(p!=NULL){
对于(p=family;p!=NULL;p=p->next){
如果(id==p->编号){
计数=1;
打破
}
}
}
//如果count为1,则我们知道函数找到了该特定用户
如果(计数=1){
printf(“用户发现:%s,%s\n”,p->last\u name,p->first\u name);
}否则{
printf(“未找到用户”);
}
}
//函数printList打印整个族
无效打印列表(结构用户*族)
{
结构用户*p;
printf(“用户ID:\t列表名:\t列表名:\n”);
对于(p=family;p!=NULL;p=p->next){
printf(“%d\t\t%s\t\t%s\n”,p->number,p->last\u name,p->first\u name);
}
}
//函数clearList清除所有链接列表
无效清除列表(结构用户*族)
{
结构用户*p;
while(family!=NULL){
p=家庭;
家庭=家庭->下一步;
如果(p!=NULL){
自由基(p);
}
}
}

我认为重叠比较运算符是一个更好的主意,然后使用一些现有算法对列表进行排序。

问题在于比较节点的方式:

for (cur=family, prev = NULL; cur != NULL 
    && (strcmp(new_node->first_name,cur->first_name) < 0) 
    && (strcmp(new_node->last_name,cur->last_name) < 0); 
        prev = cur, cur = cur->next) { ... }
for(cur=family,prev=NULL;cur!=NULL
&&(strcmp(新节点->第一个名称,cur->第一个名称)<0)
&&(strcmp(新节点->姓氏,cur->姓氏)<0);
prev=cur,cur=cur->next){…}
应跳过具有较小族或(相同族名和较小名)的节点。通过以下方式修复比较:

for (cur=family, prev = NULL;
     cur != NULL 
     && ((strcmp(new_node->first_name, cur->first_name) < 0) 
     ||  ((strcmp(new_node->first_name, cur->first_name) == 0)
     &&   (strcmp(new_node->last_name,cur->last_name) < 0))); 
     prev = cur, cur = cur->next) { ... }
for(cur=family,prev=NULL;
cur!=NULL
&&((strcmp(新节点->第一个名称,cur->第一个名称)<0)
||((strcmp(新节点->第一个名称,cur->第一个名称)=0)
&&(strcmp(新节点->姓氏,cur->姓氏)<0);
prev=cur,cur=cur->next){…}
并简化后续代码。实际上,您不需要任何代码。循环将在插入点停止。只需检查是否存在相同的姓和名(但如果有两个John Does怎么办?),并在
prev
cur
之间插入,或者在
family
之前插入,如果
prev
NULL

for的
循环看起来很难看:难以阅读,e
for (cur=family, prev = NULL;
     cur != NULL 
     && ((strcmp(new_node->first_name, cur->first_name) < 0) 
     ||  ((strcmp(new_node->first_name, cur->first_name) == 0)
     &&   (strcmp(new_node->last_name,cur->last_name) < 0))); 
     prev = cur, cur = cur->next) { ... }
 for (cur=family, prev = NULL;
        cur != NULL && (strcmp(new_node->first_name,cur->first_name) < 0) 
                    && (strcmp(new_node->last_name,cur->last_name) < 0); 
                prev = cur, cur = cur->next) 
(cur=family, family exist)
cur != NULL -> True
(Alex == Alex)
((strcmp(new_node->first_name,cur->first_name) -> 0) < 0 -> False
(Andrew > Alex)
((strcmp(new_node->last_name,cur->last_name) -> 1) < 0 -> False
True && False && False -> False
if((strcmp(new_node->first_name,cur->first_name) == 0)) 

if((strcmp(new_node->first_name,cur->first_name) < 0)) break;
;
           for (cur=family, prev = NULL; cur!=NULL && ((strcmp(new_node->first_name,
           cur->first_name)>0) || ((strcmp(new_node->first_name,
            cur->first_name)==0)&&(strcmp(new_node->last_name,
            cur->last_name)>0))); prev = cur, cur = cur->next);

      new_node->next = cur;
           if(prev==NULL)
            return new_node;
           else {
           prev->next = new_node;
           return family;
           }