1101 [填空题]链表的排序 SCAU

题目:先创建一个链表(链表中各结点未按学号由小到大排序),然后调用sort函数,将链表中各结点按学号由小到大排序

法一(超时)
这个题我一开始的思路是利用冒泡的思想,当当前结点比next结点大的时候,交换两者next所指向内容。
比如链表1-5-4-6 , 当指针p指向5所在结点的时候,发现p->next的num小于当前的num,这时候我要令p1=p->next(4所在结点), 让(5)p->next指向 (6)p1->next, 再让 (4)p1->next指向(5)p,最后再让(1)pre接上(4)p1,这样,链表的结点顺序就变成了 1-4-5-6。(注意如果是第一位的话就不用使用pre指针)

#include "stdio.h"
#include "malloc.h"
#define LEN sizeof(struct student)

struct student
{
     long num;
     int score;
     struct student *next;
};

struct student *create(int n)
{
     struct student *head=NULL,*p1=NULL,*p2=NULL;
     int i;
     for(i=1;i<=n;i++)
     {  p1=(struct student *)malloc(LEN);
        scanf("%ld",&p1->num);
        scanf("%d",&p1->score);
        p1->next=NULL;
        if(i==1) head=p1;
        else p2->next=p1;
        p2=p1;
      }
      return(head);
}

void print(struct student *head)
{
    struct student *p;
    p=head;
    while(p!=NULL)
    {
        printf("%8ld%8d",p->num,p->score);
        p=p->next;
        printf("\n");
    }
}

struct student *insert(struct student *head, struct student *stud)
{  struct student *p0,*p1,*p2;
    p1=head;  p0=stud;
    if(head==NULL)
      {head=p0;}
    else
   { while( (p0->num > p1->num) && (p1->next!=NULL) )
       { p2=p1;     p1=p1->next;}
     if( p0->num < p1->num )
      {  if( head==p1 ) head=p0;
           else p2->next=p0;
         p0->next=p1; }
     else {  p1->next=p0;}
     }
    return(head);
}

struct student *del(struct student *head,long num)
{
    struct student *p1,*p2;
    p1=head;
    while(p1!=NULL)
    {
        if(p1->num == num)
        {
          if(p1 == head) head=p1->next;
          else p2->next=p1->next;
          free(p1);
          break;
        }
        p2=p1;
        p1=p1->next;
    }
    return(head);
}

struct student *sort(struct student *head)
{
            struct student *p1,*p2, *p3,*pre;
            int i,j;
            p1=head;
           int count=0;
           while(p1)
           {
               count++;
               p1=p1->next;
           }
         //  printf("%d\n",count);
           for(i=1;i<=count;i++)
           {
               p1=head;
               pre=p1;
               int count1=0;
               while(p1->next!=NULL)
               {
                      count1++;
                      if(count1<=i)   continue;

                      p2=p1->next;
                      if(p1->num>p2->num)
                      {
                          if(p1==head)
                             {
                                 p3=p2->next;
                                p1->next=p3;
                                p2->next=p1;
                                pre=p2;
                              }
                              else
                              {
                                  p3=p2->next;
                                  p1->next=p3;
                                  p2->next=p1;
                                  pre->next=p2;
                                  pre=p1;
                              }
                             //  print(head);
                       //   printf("%d %d %d\n",p1->num,p2->num,p3->num);

                      }
                      else
                      {
                         pre=p1;
                          p1=p1->next;

                      }

                    //  printf("1\n");

               }

           }
           return head;
}

main()
{
    struct student *head,*stu;
    int n;
    scanf("%d",&n);
    head=create(n);
    print(head);
    head=sort(head);
    print(head);
}
发现可以

在这里插入图片描述
发现可以达到预期效果

但是,这个方法的循环次数太多,哪怕优化后,对内层加上了小于i就continue,也还是超时。
在这里插入图片描述
法二
既然改变链表结点顺序会超时,那么就退一步,我只要保持冒泡,将满足判断语句(后比前小)结构体里面的成员替换就好了。
比如1-5-4-6
当p指向5时,发现下一个的num更小,那么我就把下一个结点的num和我当前的num换一下,结点还是原来的结点,无需变动,只需改变成员变量就行了。

#include "stdio.h"
#include "malloc.h"
#define LEN sizeof(struct student)

struct student
{
     long num;
     int score;
     struct student *next;
};

struct student *create(int n)
{
     struct student *head=NULL,*p1=NULL,*p2=NULL;
     int i;
     for(i=1;i<=n;i++)
     {  p1=(struct student *)malloc(LEN);
        scanf("%ld",&p1->num);
        scanf("%d",&p1->score);
        p1->next=NULL;
        if(i==1) head=p1;
        else p2->next=p1;
        p2=p1;
      }
      return(head);
}

void print(struct student *head)
{
    struct student *p;
    p=head;
    while(p!=NULL)
    {
        printf("%8ld%8d",p->num,p->score);
        p=p->next;
        printf("\n");
    }
}

struct student *insert(struct student *head, struct student *stud)
{  struct student *p0,*p1,*p2;
    p1=head;  p0=stud;
    if(head==NULL)
      {head=p0;}
    else
   { while( (p0->num > p1->num) && (p1->next!=NULL) )
       { p2=p1;     p1=p1->next;}
     if( p0->num < p1->num )
      {  if( head==p1 ) head=p0;
           else p2->next=p0;
         p0->next=p1; }
     else {  p1->next=p0;}
     }
    return(head);
}

struct student *del(struct student *head,long num)
{
    struct student *p1,*p2;
    p1=head;
    while(p1!=NULL)
    {
        if(p1->num == num)
        {
          if(p1 == head) head=p1->next;
          else p2->next=p1->next;
          free(p1);
          break;
        }
        p2=p1;
        p1=p1->next;
    }
    return(head);
}

struct student *sort(struct student *head)
{
            struct student *p1,*p2, *p3,*pre;
            int i,j;
            for(p1=head;p1!=NULL;p1=p1->next)
            {
              //     p3=p1;
                for(p2=p1->next;p2!=NULL;p2=p2->next)
                {
                        if(p2->num<p1->num)
                        {
                            int t;
                             t = p1->num;
                             p1->num=p2->num;
                             p2->num=t;
                             t=p1->score;
                             p1->score=p2->score;
                             p2->score=t;
                        }
                }
            }

           return head;
}

main()
{
    struct student *head,*stu;
    int n;
    scanf("%d",&n);
    head=create(n);
    print(head);
    head=sort(head);
    print(head);
}

在这里插入图片描述
这样就快了很多。至于还有没有更好的方法,欢迎指出。

发布了33 篇原创文章 · 获赞 23 · 访问量 1839

猜你喜欢

转载自blog.csdn.net/qq_45492531/article/details/103270122
今日推荐