一条链表的排序和两条链表的合并(顺序是按照学生的学号递增顺序)
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;
}