无序链表合并

目录

链表结构

创建链表

链表排序

合并有序链表

打印链表

清除链表

链表结构

typedef struct node {
	int data;
	struct node* next;
}NODE;

创建链表

同样采用前插法进行创建(上一篇介绍

**注意:为避免警告,当申请完内存后,需要判断是否分配成功,使用malloc或者new申请内存时,如果分配失败返回NULL或者nullptr。另外分配失败后注意将链表空间释放。

代码:

NODE* createList(int a[],int len)
{
	NODE* head = NULL;
	for (int i = len-1; i >= 0; i--)
	{
		NODE* p = (NODE*)malloc(sizeof(NODE));
		if (p == NULL)
		{
			printf("内存分配失败\n");
			freeList(head);
			return NULL;
		}
		p->data = a[i];
		p->next = head;
		head = p;
	}
	return head;
}

链表排序

采用归并法进行排序。

排序步骤:

  • 对链表进行拆分,直到链表只有一个元素
  • 对拆分后的链表按照有序链表合并的方法进行合并

拆分步骤:

  • 采用快慢指针法寻找链表的中点
  • 按照中点将链表拆分为左右两个链表

寻找链表中点代码:

NODE* midNode(NODE* head)
{
	if (!head || !head->next) return head;
	NODE* slow = head, * fast=head;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
	}
	return slow;
}

排序代码:

NODE* sortList(NODE* head)
{
	if (!head || !head->next) return head;
	NODE* mid_node = midNode(head);
	NODE* right = sortList(mid_node->next);
    // 保证左侧链表的最后一个结点的next为NULL
	mid_node->next = NULL;
	NODE* left = sortList(head);
    // 按照有序链表进行排序
	return mergeList(left, right);
}

合并有序链表

采用双指针法,分别指向两个有序链表的首元结点。

步骤:

  • 创建头结点,并创建临时指针temp指向头结点,时刻指向待插入位置。(临时指针的另一个作用是保证头结点位置不变,保证后续可以根据头结点找到链表)
  • 将data小的结点插入到头结点的next,结点后移,temp也需要后移
  • 当两个链表有一个为NULL时,将非空的链表直接插入到当前位置的下一个结点。

代码:

NODE* mergeList(NODE* LA, NODE* LB)
{
	NODE* LC = (NODE*)malloc(sizeof(NODE));
	if (LC == NULL)
	{
		printf("内存分配失败\n");
		free(LC);
		return NULL;
	}
	NODE* temp = LC;
	while (LA && LB)
	{
		if (LA->data < LB->data)
		{
			temp->next = LA;
			LA = LA->next;
		}
		else {
			temp->next = LB;
			LB = LB->next;
		}
		temp = temp->next;
	}
    // 将非空链表全部插入到当前结点的next
	if (LA!=NULL) temp->next = LA;
	if (LB!=NULL) temp->next = LB;
	return LC->next;
}

打印链表

void printList(NODE* head)
{
	while (head)
	{
		printf("%d->", head->data);
		head = head->next;
	}
	printf("%s\n", "NULL");
}

清除链表

与打印链表的思路一样,传入头结点,只要当前结点非空,便依次释放结点空间。

**注意:需要使用临时结点保存head的下一个结点的信息,防止释放head后,找不到下一个结点。

代码:

void freeList(NODE* head)
{
	while (head)
	{
		// 采用临时指针记录当前结点的下一个结点 
		NODE* temp = head;
		head = head->next;
		free(temp);
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值