将两个升序排列的单链表合并为一个降序排列的单链表且不增加新的结点

#include<stdio.h>
#include<stdlib.h>

typedef struct node{
	char data;
	struct node *next;
}LNode;

LNode *creat_linklist()
{
	LNode *p,*q,*head;
	int i,n;
	head=(LNode*)malloc(sizeof(LNode));
	head->next=NULL;
	p=head;
	q=p;
	printf("请输入单链表长度:\n");
	scanf("%d",&n);
	printf("请输入值:\n");
	for(i=1;i<=n;i++)
	{
		p=(LNode*)malloc(sizeof(LNode));
		scanf("%d",&p->data);
		p->next=NULL;
		q->next=p;
		q=p;
	}
	return head;
}

void merge(LNode *A,LNode *B,LNode **C)
{
	LNode *p,*q,*s;
	p=A->next;
	q=B->next;
	*C=A;
	(*C)->next=NULL;
	free(B);
	while(p!=NULL&&q!=NULL)
	{
		if(p->data<q->data)
		{
			s=p;
			p=p->next;
		}
		else
		{
			s=q;
			q=q->next;
		}
		s->next=(*C)->next;
		(*C)->next=s;
	}
	if(p==NULL)
		p=q;
	while(p!=NULL)
	{
		s=p;
		p=p->next;
		s->next=(*C)->next;
		(*C)->next=s;
	}
}

void print(LNode *p)
{
	p=p->next;
	while(p!=NULL)
	{
		printf("%5d",p->data);
		p=p->next;
	}
	printf("\n");
}

void main()
{
	LNode *A,*B,*C;
	printf("*** 创建单链表A ***\n");
	A=creat_linklist();
	printf("您创建的单链表A为:\n");
	print(A);
	printf("\n");
	printf("*** 创建单链表B ***\n");
	B=creat_linklist();
	printf("您创建的单链表B为:\n");
	print(B);
	printf("\n合并之后的单链表C为:\n");
	merge(A,B,&C);
	print(C);
}

首先需要判断空链表的情况,若其中一个链表为空,只需要将另一个链表作为合并后的链表即可。否则,需要将两个链表逐个比较大小,将较大的结点插入到链表的头部,直到其中一个链表为空。最后将剩余的结点插入到链表的头部即可。 以下是算法的详细实现: ```c #include <stdio.h> #include <stdlib.h> // 定义链表结点类型 typedef struct Node { int data; struct Node* next; } Node; // 将元素插入到链表头部 void insertAtHead(Node** head, int value) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = value; newNode->next = *head; *head = newNode; } // 合并两个链表一个降序排列链表 Node* mergeLists(Node* Pa, Node* Pb) { // 判断空链表的情况 if (Pa == NULL) { return Pb; } else if (Pb == NULL) { return Pa; } Node* head = NULL; // 合并后的链表结点 while (Pa != NULL && Pb != NULL) { if (Pa->data >= Pb->data) { // 当前Pa的值大于等于当前Pb的值 insertAtHead(&head, Pa->data); Pa = Pa->next; // 数组Pa往后移动 } else { // 当前Pb的值大于当前Pa的值 insertAtHead(&head, Pb->data); Pb = Pb->next; // 数组Pb往后移动 } } // 将剩余的结点插入到链表头部 while (Pa != NULL) { insertAtHead(&head, Pa->data); Pa = Pa->next; } while (Pb != NULL) { insertAtHead(&head, Pb->data); Pb = Pb->next; } return head; // 返回合并后的链表结点 } // 打印链表中的元素 void printList(Node* head) { while (head != NULL) { printf("%d ", head->data); head = head->next; } printf("\n"); } int main() { // 初始化两个升序排列链表 Node* Pa = NULL; insertAtHead(&Pa, 8); insertAtHead(&Pa, 6); insertAtHead(&Pa, 4); insertAtHead(&Pa, 2); printf("Pa:"); printList(Pa); Node* Pb = NULL; insertAtHead(&Pb, 9); insertAtHead(&Pb, 7); insertAtHead(&Pb, 5); insertAtHead(&Pb, 3); insertAtHead(&Pb, 1); printf("Pb:"); printList(Pb); // 合并两个链表一个降序排列链表 Node* Pc = mergeLists(Pa, Pb); printf("Pc:"); printList(Pc); return 0; } ``` 运行结果如下: ``` Pa:2 4 6 8 Pb:1 3 5 7 9 Pc:9 8 7 6 5 4 3 2 1 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值