已有a,b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号升序排列。

已有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);
		}		
	}
}

你可能感兴趣的:(C程序设计)