运行超时是什么原因呢

#include<stdio.h>
#include<stdlib.h>
typedef struct link
{
    int data;
    struct link *pNext;
}Node,*PNode;

PNode creat()
{
    PNode L=NULL;
    L=(PNode)malloc(sizeof(Node));
    if(!L)
        return 0;
    L->pNext=NULL;
    return L;
}

void Insert(PNode L,int e)
{
    PNode pcur=NULL,pnew=NULL,prear=NULL;
    pnew=(PNode)malloc(sizeof(Node));
    if(!pnew)
        pnew=NULL;
    pnew->pNext=NULL;
    pnew->data=e;
    if(L->pNext==NULL)
        L->pNext=pnew;
    else
    {
        pcur=L;
        prear=pcur->pNext;
        while(prear->data<=pnew->data)
        {
            pcur=pcur->pNext;
            prear=pcur->pNext;
            if(prear==NULL)
                break;
        }
        pnew->pNext=prear;
        pcur->pNext=pnew;
    }
}
void print(PNode L)
{
    PNode p=NULL;
    p=L->pNext;
    while(p)
    {
        printf("%d->",p->data);
        p=p->pNext;
    }
    printf("\n");
}
void destroy(PNode L)
{
    PNode p=NULL;
    while(L)
    {
        p=L->pNext;
        free(L);
        L=p;
    }
}

void Reverse(PNode L)
{
    PNode pcur=NULL,pre=NULL,prear=NULL;
    pre=L->pNext;

    if(pre==NULL)
        printf("该链表为空表\n");
    else
    {
        pcur=pre->pNext;
        prear=pcur->pNext;
        while(prear!=NULL)
    {
        pcur->pNext=pre;
        pre=pcur;
        pcur=prear;
        prear=prear->pNext;
    }
    pcur->pNext=pre;
    L->pNext=pcur;
    }

    print(L);
}
int main()
{
    PNode Lz=NULL,Lf=NULL;
    int a;
    Lz=creat();
    Lf=creat();
    while(scanf("%d",&a)==1)
    {

        if(a>0)
            Insert(Lz,a);
        else
            Insert(Lf,a);
    }

    print(Lz);
    print(Lf);

    Reverse(Lz);
    Reverse(Lf);

    destroy(Lz);
    destroy(Lf);
    return 0;
}


1.先在自己电脑的环境里运行,确定这代码是能运行的,没有死循环
2.测试一下代码运行到底需要多久,然后针对性的优化
3.只运行一次就结束进程的程序,没必要循环delete,进程结束了自然所有内存都释放了
4.pcur和prear既然后面只需要用到一个,就不要在循环里一起操作它俩,除了双倍浪费时间没有意义

链表逆置不对,修改如下,改动处见注释,供参考:

#include<stdio.h>
#include<stdlib.h>
typedef struct link
{
    int data;
    struct link* pNext;
}Node, * PNode;

PNode creat()
{
    PNode L = NULL;
    L = (PNode)malloc(sizeof(Node));
    if (!L)
        return 0;
    L->pNext = NULL;
    return L;
}

void Insert(PNode L, int e)
{
    PNode pcur = NULL, pnew = NULL, prear = NULL;
    pnew = (PNode)malloc(sizeof(Node));
    if (!pnew)
        pnew = NULL;
    pnew->pNext = NULL;
    pnew->data = e;
    if (L->pNext == NULL)
        L->pNext = pnew;
    else
    {
        pcur = L;
        prear = pcur->pNext;
        while (prear->data <= pnew->data)
        {
            pcur = pcur->pNext;
            prear = pcur->pNext;
            if (prear == NULL)
                break;
        }
        pnew->pNext = prear;
        pcur->pNext = pnew;
    }
}
void print(PNode L)
{
    PNode p = NULL;
    p = L->pNext;
    while (p)
    {
        printf("%d->", p->data);
        p = p->pNext;
    }
    printf("\n");
}
void destroy(PNode L)
{
    PNode p = NULL;
    while (L)
    {
        p = L->pNext;
        free(L);
        L = p;
    }
}

void Reverse(PNode L)
{
    PNode pcur = NULL, pre = NULL, prear = NULL;
    pre = L->pNext;
    
    if (pre == NULL)
        printf("该链表为空表\n");
    else
    {
        L->pNext = NULL;     // 修改
        //pcur = pre->pNext;
        //prear = pcur->pNext;
        while (pre != NULL)   //(prear != NULL)
        {
            pcur = pre;
            //pre = pcur;
            //pcur = prear;
            pre = pre->pNext;

            pcur->pNext = L->pNext;
            L->pNext = pcur;
        }
    }
    print(L);
}
int main()
{
    PNode Lz = NULL, Lf = NULL;
    int a;
    Lz = creat();
    Lf = creat();
    while (scanf("%d", &a) == 1 && a)  // 修改 输入 a = 0 时结束输入
    {

        if (a > 0)
            Insert(Lz, a);
        else if (a < 0)        // 修改
            Insert(Lf, a);
    }

    print(Lz);
    print(Lf);

    Reverse(Lz);
    Reverse(Lf);

    destroy(Lz);
    destroy(Lf);
    return 0;
}

本次回答,借鉴于GPT4

  1. 链表过长。如果插入的节点数目过多,链表会变得极长,Reverse()函数在反转过程中需要遍历整个链表,时间复杂度为O(n),可能导致超时。解决办法:避免产生过长链表,合理设置链表节点数目的上限。
  2. 反转算法低效。当前使用的反转算法是将每两个相邻节点反转,时间复杂度较高。更高效的算法是尾插法,只需要遍历链表一次。解决办法:采用尾插法反转链表,时间复杂度为O(n)。
  3. 动态内存申请失败。如果malloc()申请内存失败,程序会陷入死循环,耗尽资源导致超时。解决办法:检查每次内存申请的返回值,如果失败则终止程序运行。
  4. scanf()输入超时。如果输入过多数据导致scanf()无法及时读入,也会产生超时。

解决办法:合理限制scanf()的输入数据量。除上述方法外,也可以考虑:

  • 优化代码运行效率,减少不必要循环和递归等
  • 避免产生资源泄漏,及时释放动态申请的内存
  • 选择更高效的数据结构,如数组等

我的建议是:

  1. 检查链表长度和输入数据量,设置合理的限制
  2. 采用尾插法算法反转链表,时间复杂度为O(n)
  3. 检查内存申请情况,失败则终止程序
  4. 优化代码,减少不必要操作
  5. 尽量选择时间复杂度更低的数据结构