数据结构C语言链表输入排序问题 20C

题目:

持续输入 学号,姓名,地址

-1终止输入

再按照学号从小到大顺序输出

个人感觉问题可能出在31行到38行
插入在链表最前面的时候会出现问题,其他情况没有问题

测试 输入会错误的情况(插在开头):
3,sfdfs,sdfsfd
2,sdf,sdf,sfd
-1

测试 输入会正确的情况:
3,sdf,sd,sfd
5,fsd,sdf
4,dsf,sdf
-1

/////姓名和地址就乱打几个字符了。。。

下面是关于链的的数据的调试截图(输出_会错误的情况_,数据见上文 )

图片说明

直到输入 —1终止前 ,都是正确的(↑↑↑第一张调试图,排序也是对的)

但是终止后,就会无限输出开头的(↓↓↓最后输入的插到开头的那个数)

主链变成next永远指向自己的。

图片说明

虽然是用双链表写的,但是没什么关系。
个人感觉问题在出在指针返还值或者函数返还值上面,_步骤应该都是没有问题的_,调试了很多遍

 #define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef  struct node
{
    char    name[20];
    char    add[20];
    int nu;

    struct node *pre;
    struct node *next;
}Newnode;


Newnode sort( node *q, Newnode *inser )                                 /* sort+insert 找到位置插入 */
{
    Newnode *temp = q;


    while ( 1 )
    {
        if ( temp->next == NULL && temp->nu < inser->nu )       /* 插在尾的情况,插入数大于所有temp +  第一个数时插在后面 */
        {
            temp->next  = inser;
            inser->pre  = temp;
            return(*q);
        }


        if ( temp->pre == NULL && temp->nu > inser->nu )        /*  第一个数时插在前面 */
        {                                                       /*  printf("okOK"); */
            /*  temp->pre=inser; */
            inser->next = temp;

            return(*inser);
        }
    }
    inser->next = temp;
    inser->pre  = temp->pre;
    temp->pre->next = inser;
    temp->pre   = inser;

    return(*q);
}


Newnode add( Newnode *q )     //q就是主链的地址
{
    int count = 0;


    while ( 1 )
    {
        Newnode *newnode;
        newnode = (Newnode * ) malloc( sizeof(Newnode) );
        scanf( "%d,", &newnode->nu );
        if ( newnode->nu == -1 )
        {
            return(*q);
        }
        newnode->next   = NULL;
        newnode->pre    = NULL;
        scanf( "%[^,]%[^\n]", newnode->name, newnode->add );


        if ( q->pre == NULL && q->next == NULL && count == 0 )
        {
            q = newnode;
            count++;                        /* 第一个数的输入,只输入一次 */
            continue;
        }else
            *q = sort( q, newnode );        /* 从第二个数开始就插入,这里的指针传递对吗。。。 */
    }
    return(*q);
}


void printall( Newnode *q )
{
    Newnode *temp = q; /* temp当前指针 */
    printf( "%d %s %s\n", q->nu, q->name, q->add );
    temp = temp->next;
    /* printf("%d %s %s\n",temp->nu,temp->name,temp->add); */
    while ( temp != NULL )
    {
        printf( "%d %s %s\n", temp->nu, temp->name, temp->add );
        temp = temp->next;
    }
/*  printf("%d %s %s\n",temp->nu,temp->name,temp->add); */
}


/* ////////////////////// */

int main( void )
{
    char inpu; int inpu2;

    Newnode p;

    p.pre   = NULL; p.next = NULL;
    p   = add( &p );

    printall( &p );
}

第一个特别输入
其他 找到位置,然后插入,排序一个插入一个。
调试调试吧。
再次说一下,步骤应该是没有问题的。(除了插在开头的情况会出现错误)调试了很多数据了。感觉问题应该出在指针返还上面。

1

3个回答

错误有两点:
1是你的sort函数本身排序算法有问题
2.在add函数中你用你sort函数返回一个链表节点赋值给了一个已经在你链表中排序过的节点,造成本身有序的链表又无序了。
改了一下
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
typedef struct node
{
char name[20];
char add[20];
int nu;

struct node *pre;
struct node *next;

}Newnode;

Newnode sort( Newnode *q, Newnode *inser )

{
Newnode *temp = q;

while ( 1 )
{
    if(temp->nu == inser->nu){
        printf("error:duplicate num\n");
        exit(0);
    }
    if ( temp->next == NULL && temp->nu < inser->nu )      
    {
        temp->next  = inser;
        inser->pre  = temp;
        return(*q);
    }

    if ( temp->pre == NULL && temp->nu > inser->nu )        
    {                                                       
        /*  temp->pre=inser; */
        inser->next = temp;

        return(*inser);
    }
    if ( temp->pre != NULL && temp->nu > inser->nu )        
            {                                                    
                temp->pre->next=inser;
                inser->next=temp;
                inser->pre =temp->pre;
                temp->pre=inser;
                return(*q);
            }
    if ( temp->next != NULL && temp->nu < inser->nu )        
            {                                                      

                temp=temp->next;
            }
}

}

Newnode add( Newnode *q ) //q就是主链的地址
{
int count = 0;

while ( 1 )
{
    Newnode *newnode;
    newnode = (Newnode * ) malloc( sizeof(Newnode) );
    scanf( "%d,", &newnode->nu );
    if ( newnode->nu == -1 )
    {
        return(*q);
    }
    newnode->next   = NULL;
    newnode->pre    = NULL;
    scanf( "%[^,]%[^\n]", newnode->name, newnode->add );


    if ( q->pre == NULL && q->next == NULL && count == 0 )
    {
        q->next= newnode;
        count++;
        continue;
    }else
        q->next = sort( q->next, newnode );       
}
return(*q);

}

void printall( Newnode q )
{
Newnode *temp = q; /
temp当前指针 /
printf( "%d %s %s\n", q->nu, q->name, q->add );
temp = temp->next;
/
printf("%d %s %s\n",temp->nu,temp->name,temp->add); /
while ( temp != NULL )
{
printf( "%d %s %s\n", temp->nu, temp->name, temp->add );
temp = temp->next;
}
/
printf("%d %s %s\n",temp->nu,temp->name,temp->add); */
}

/* ////////////////////// */

int main( void )
{
char inpu; int inpu2;

Newnode p;

p.pre   = NULL; p.next = NULL;
p   = add( &p );

printall( p.next );

}

0

Newnode add( Newnode *q ) //q就是主链的地址
{
int count = 0;

while ( 1 )
{
    Newnode *newnode;
    newnode = (Newnode * ) malloc( sizeof(Newnode) );
    scanf( "%d,", &newnode->nu );
    if ( newnode->nu == -1 )
    {
        return(*q);
    }
    newnode->next   = NULL;
    newnode->pre    = NULL;
    scanf( "%[^,]%[^\n]", newnode->name, newnode->add );


    if ( q->pre == NULL && q->next == NULL && count == 0 )
    {
        q = newnode;
        count++;                        /* 第一个数的输入,只输入一次 */
        continue;                       《-------------
    }else
        *q = sort( q, newnode );        /* 从第二个数开始就插入,这里的指针传递对吗。。。 */
}
return(*q);

}

这里的continue,语句的话好像是用break。continue是跳出本次循环,执行下一次循环。这里感觉你应该是要跳出整个循环体,而不是一次循环,break就是用于跳出循环体。

Newnode sort( node q, Newnode *inser ) / sort+insert 找到位置插入 */
{
Newnode *temp = q;

while ( 1 )
{
    if ( temp->next == NULL && temp->nu < inser->nu )       /* 插在尾的情况,插入数大于所有temp +  第一个数时插在后面 */
    {
        temp->next  = inser;
        inser->pre  = temp;
        return(*q);
    }


    if ( temp->pre == NULL && temp->nu > inser->nu )        /*  第一个数时插在前面 */
    {                                                       /*  printf("okOK"); */
        /*  temp->pre=inser; */
        inser->next = temp;

        return(*inser);
    }
}
inser->next = temp;
inser->pre  = temp->pre;
temp->pre->next = inser;
temp->pre   = inser;

return(*q);

}
这里的话while死循环包裹了上面,也没有跳出语句下面:
inser->next = temp;
inser->pre = temp->pre;
temp->pre->next = inser;
temp->pre = inser;

return(*q);

这几句估计不会执行,输入两个前插或者两个后插 估计就会死循环吧。

我也不是高手,说错请谅解,谢谢!!

-1

既然会调试,那就一个节点一个节点的跟代码
这代码,。。->nu输入一个1,然后输入3,再输入2就死循环了

-1
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!