已有a,b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号升序排列。
方法一:(链表删除操动态初始化链表,其余操作动态静态初始化都行)
#include
#include
//声明结构体struct Student
struct Student
{
int num;
float score;
struct Student *prev;
struct Student *next;
};
struct Student *input(int n); //声明输入函数
void append(struct Student **head2, struct Student *stu);//声明建立链表操作
struct Student *merge(struct Student *stu1, struct Student *stu2, int m);//声明合并函数
void print(struct Student *stu); //声明输出函数
int main()
{
struct Student *a,*b;
a=input(3); //调用输入函数,生成a链表
b=input(2); //调用输入函数,生成b链表
print(merge(a, b, 3)); //调用输出函数,参数为合并函数返回指针值
return 0;
}
//输入函数
struct Student *input(int n)
{
struct Student *head = NULL, *stu;
for (int i=1; i<=n; i++)//动态初始化链表
{
stu = (struct Student*)malloc(sizeof(struct Student));
printf("Please enter No.%d student info: ", i);
scanf("%d %f", &stu->num,&stu->score);
append(&head, stu);
}
printf("\n");
return head;
}
//建立链表操作
void append(struct Student **head2, struct Student *stu)
{
stu->next = NULL;
if (*head2 == NULL)
{
stu->prev = NULL;
*head2 = stu;
}
else
{
struct Student *p = *head2;
while (p->next!=NULL)
p=p->next;
p->next = stu;
stu->prev = p;
}
}
//合并函数
struct Student *merge(struct Student *stu1, struct Student *stu2, int m)
{
struct Student *p = stu1;
while (p->next!=NULL)
p=p->next;
p->next=stu2;
struct Student *q, temp;
for (p=stu1; p!=NULL; p=p->next)//直接选择排序法对链表的学号由小到大排序,对学号排序就要交换学号,但由于一个学号对应一个成绩,所以也要对成绩排序
{
for (q=p->next; q!=NULL; q=q->next)//同时也要注意交换时只交换结构体变量中的学号和成绩,next指针不交换改变,为了保持原链表的链接顺序。
{
if (p->num>q->num)
{
temp.num=p->num;
p->num=q->num;
q->num=temp.num;
temp.score=p->score;
p->score=q->score;
q->score=temp.score;
}
}
}
return stu1;
}
//输出函数
void print(struct Student *stu)
{
struct Student *p;
for (p=stu; p!=NULL; p=p->next)
{
printf("%d %.2f\n", p->num, p->score);
}
}
方法一简化版:(简化input函数)
#include
#include
//声明结构体struct Student
struct Student
{
int num;
float score;
struct Student *next;
};
void input(struct Student *stu, int n); //声明输入函数
struct Student *merge(struct Student *stu1, struct Student *stu2, int m); //声明合并函数,返回指针值
void print(struct Student *stu); //声明输出函数
int main()
{
struct Student *a=(struct Student*)malloc(3*sizeof(struct Student));//相当于struct Student a[3]
struct Student *b=(struct Student*)malloc(2*sizeof(struct Student));//相当于struct Student b[3]
input(a, 3); //调用输入函数,生成a链表
input(b, 2); //调用输入函数,生成b链表
print(merge(a, b, 3)); //调用输出函数,参数为合并函数返回指针值
return 0;
}
//输入函数
void input(struct Student *stu, int n)//先建立两个链表
{
int i=0;
struct Student *p;
for (p=stu; p<stu+n; p++, i++)
{
printf("Please enter No.%d student info; ", i+1);
scanf("%d %f", &p->num, &p->score);
i==n-1 ? (p->next=NULL) : (p->next=&stu[i+1]);
}
}
//合并函数
struct Student *merge(struct Student *stu1, struct Student *stu2, int m)
{
stu1[m-1].next=stu2; //再合并,将a链表最末尾的next指向b链表首地址
struct Student *p, *q, temp;
for (p=stu1; p!=NULL; p=p->next)//直接选择排序法对链表的学号由小到大排序,对学号排序就要交换学号,但由于一个学号对应一个成绩,所以也要对成绩排序
{
for (q=p->next; q!=NULL; q=q->next)//同时也要注意交换时只交换结构体变量中的学号和成绩,next指针不交换改变,为了保持原链表的链接顺序。
{
if (p->num>q->num)
{
temp.num=p->num;
p->num=q->num;
q->num=temp.num;
temp.score=p->score;
p->score=q->score;
q->score=temp.score;
}
}
}
return stu1;
}
//输出函数
void print(struct Student *stu)
{
struct Student *p;
for (p=stu; p!=NULL; p=p->next)
{
printf("%d %.2f\n", p->num, p->score);
}
}
方法二:
#include
#include
struct Student
{ //声明结构体struct Student
int num;
char name[20];
struct Student *prev;
struct Student *next;
};
struct Student *input(int);
void append(struct Student **, struct Student *);
void merge(struct Student **, struct Student *);
void sort(struct Student **);
void swap(struct Student *, struct Student *);
void del_item(struct Student **, struct Student *);
void del_list(struct Student **, struct Student *);
void print(struct Student *);
int main()
{
struct Student *a, *b; //定义链表a和b
a = input(3); //调用输入函数,输入a链表
b = input(2); //调用输入函数,输入b链表
merge(&a, b); //合并a和b
sort(&a); //将a进行排序
print(a); //输出a
return 0;
}
//输入函数
struct Student *input(int n)
{
struct Student *head = NULL, *stu;
for (int i=1; i<=n; i++)
{
stu = (struct Student*)malloc(sizeof(struct Student));
printf("Please enter No.%d student info: ", i);
scanf("%d %s", &stu->num, stu->name);
append(&head, stu);
}
printf("\n");
return head;
}
//建立链表操作
void append(struct Student **head, struct Student *stu)
{
stu->next = NULL;
if (*head == NULL)
{
stu->prev = NULL;
*head = stu;
}
else
{
struct Student *p = *head;
while (p->next!=NULL)
p=p->next;
p->next = stu;
stu->prev = p;
}
}
//合并函数
void merge(struct Student **list1, struct Student *list2)
{
if (*list1 == NULL)
{
*list1 = list2;
}
else
{
struct Student *p = *list1;
while (p->next!=NULL)
p=p->next;
p->next=list2;
list2->prev=p;
}
}
//排序函数
void sort(struct Student **head)
{
struct Student *p, *q, *i;
int min;
for (q=*head; q!=NULL; q=q->next)
{
for (p=q; p!=NULL; p=p->next)
{
if (min > p->num || p == q)
{
i = p;
min = p->num;
}
}
swap(q, i);
}
}
//交换元素函数
void swap(struct Student *a, struct Student *b)
{
struct Student *ap, *an, *bp, *bn;
struct Student stu;
ap = a->prev;
an = a->next;
bp = b->prev;
bn = b->next;
stu = *a;
*a = *b;
*b = stu;
a->prev = ap;
a->next = an;
b->prev = bp;
b->next = bn;
}
//删除多个节点函数
void del_list(struct Student **list1, struct Student *list2)
{
struct Student *p, *q;
for (q=list2; q!=NULL; q=q->next)
{
for (p=*list1; p!=NULL; p=p->next)
{
if (p->num == q->num)
{
del_item(list1, p);
}
}
}
}
//删除单个节点函数
void del_item(struct Student **head, struct Student *p)
{
if (p==*head)
*head=p->next;
if (p->prev!=NULL)
p->prev->next=p->next;
if (p->next!=NULL)
p->next->prev=p->prev;
free(p);
}
//输出函数
void print(struct Student *stu)
{
if(stu == NULL)
printf("Empty Linked list.\n");
else
{
struct Student *p;
for (p=stu; p!=NULL; p=p->next)
{
printf("%d %s\n", p->num, p->name);
}
}
}