C语言复习8

一条链表的排序和两条链表的合并(顺序是按照学生的学号递增顺序)

1.对于一条链表的排序

1)空链表

2)链表只有一个元素

3)链表有多个元素:我的思路是把这条C链表分成两条,一条A链表先取这条C链表的前面两个并且排好顺序,一条B链表作为剩下的部分,把B链表的结点按照链表插入的思想插入到A链表中,当B链表没有元素了停止插入

2.对于两条链表的合并

我的思路是先把A和B链表都排好顺序,然后还是用链表插入的思想,把B链表的元素一个一个插入到A链表当中,当B链表没有元素了就停止插入

总的思路是:

1.结构体定义

2.创建链表的函数

3.得到链表结点的个数的函数

4.链表插入新的元素的函数

5.对一个链表进行排序的函数

6.两条链表合并的函数

7.输出链表的函数

8.主函数打印一些相关信息和调用相关的函数

#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct Student)
struct Student{
    int ID;
    char Name[10];
    struct Student*Next;
};
struct Student*Creat(void){
    struct Student*p1,*p2,*head;
    int Student_Num=0;
    p2=head=NULL;
    p1=(struct Student*)malloc(LEN);
    scanf("%d %s",&p1->ID,p1->Name);
    while(p1->ID>0){
        Student_Num++;
        if(Student_Num==1){
            p2=head=p1;
        }
        else{
            p2->Next=p1;
            p2=p1;            
        }       
        p1=(struct Student*)malloc(LEN);
        scanf("%d %s",&p1->ID,p1->Name);
    }
    if(head!=NULL)  p2->Next=NULL;
    return (head);
}
//得到链表结点的个数
int GetNum(struct Student*head){
    struct Student*Temp;
    int Num=0;
    Temp=head;
    //空链表0个结点
    if(Temp==NULL){
        Num=0;
    }
    else{
        do{
            Num++;
            Temp=Temp->Next;
        }while(Temp!=NULL);
    }
    return Num;
}
//链表插入新的元素
struct Student*Insert(struct Student*head,struct Student*stu){
    struct Student*p1,*p2;
    int Flag=0;
    p2=head;
    p1=head->Next;
    if(stu!=NULL){
        do{
            //插在头部
            if(stu->ID<head->ID){
               head=stu;
               stu->Next=p2;
               Flag=1;
            }
            //插在中间
            else if(stu->ID>p2->ID&&stu->ID<p1->ID){
                p2->Next=stu;
                stu->Next=p1;
                Flag=1;
            }       
            else if(stu->ID>p1->ID){
                //插在末尾
                if(p1->Next==NULL){
                    p1->Next=stu;
                    stu->Next=NULL;
                    Flag=1;
                }
                //跟进
                else{
                    p2=p1;
                    p1=p1->Next;
                }  
            }
        }while(Flag==0);
    }
    return (head);
}
//对一个链表进行排序
struct Student*Sort(struct Student*head){
    int Num;
    struct Student*p1,*p2,*Temp1,*Temp2;
    Num=GetNum(head);//获取结点个数
    //如果只有一个结点
    if(Num==1);
    //如果有多个,先取出前两个排好顺序,然后把剩下的链表的元素一个一个插入
    else{
        //安排好p1,p2的位置
        p1=head->Next;
        p2=head;
        //先保存要插入的元素的地址
        Temp1=p1->Next;
        //如果需要调整顺序
        if(p1->ID<p2->ID){
            p1->Next=p2;
            p2->Next=NULL;
            head=p1;
        }
        //如果不用调整顺序
        else{
            p1->Next=NULL;
        }        
        Num-=2;//Num表示拆断的第二个链表的元素有多少个
        //接下来就是将拆断的第二个链表一个一个接上去就好了
        while(Num!=0){
            if(Temp1!=NULL)   Temp2=Temp1->Next;//保存下一个要插入的            
            head=Insert(head,Temp1);
            Temp1=Temp2;
            Num--;
        }
    }   
    return (head);
}
struct Student*Combine(struct Student*headA,struct Student*headB){
    struct Student*head,*Temp;
    int NumA,NumB;
    NumA=GetNum(headA);
    NumB=GetNum(headB);
    //如果两个都是空链表
    if(NumA==0&&NumB==0){
        head=NULL;
    }
    //如果A是空链表B不是空链表
    else if(NumA==0&&NumB!=0){
        head=Sort(headB);
    }
    //如果A不是空链表B是空链表
    else if(NumA!=0&&NumB==0){
        head=Sort(headA);
    }
    //如果都不是空链表,先把两个链表排序,然后按照链表插入的思想进行合并即可
    else{
        //排好顺序
        headA=Sort(headA);
        headB=Sort(headB);
        //把B链表插到A链表中
        while(NumB!=0){
            NumB--;
            Temp=headB->Next;//保存B链表的第二个地址
            head=Insert(headA,headB);//插入
            headB=Temp;//更新B链表的头地址
        }       
    }
    return (head);
}
void Print(struct Student*head){
    struct Student*Temp;
    Temp=head;
    if(Temp!=NULL){
        do{
            printf("%d %s\n",Temp->ID,Temp->Name);
            Temp=Temp->Next;
        }while(Temp!=NULL);
    }
    else{
        printf("\n空链表!\n");
    }
}
int main(){
    struct Student*headA,*headB;
    printf("如果学生的序号输入小于等于0的数,停止链表长度增加!\n");

    printf("\nA链表:\n");
    headA=Creat();
    Print(headA);

    printf("\nB链表:\n");
    headB=Creat();
    Print(headB);

    printf("\nA链表排序:\n");
    headA=Sort(headA);
    Print(headA);

    printf("\nB链表排序:\n");
    headB=Sort(headB);
    Print(headB);

    printf("\n合并后的链表:\n");
    headA=Combine(headA,headB);
    Print(headA);

    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值