以值为基准分割带头结点的单链表

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int ElemType;
typedef struct LNode   //建立链表结构体
{
	ElemType data;
	struct LNode* next;   //还未定义别名只能用struct LNode定义next指针
}LinkList;
void InitList(LinkList*& L)   //初始化链表
{
	L = (LinkList*)malloc(sizeof(LinkList));  //创建头结点
	L->next = NULL;     //其next域置为空
}
LinkList* createNode(ElemType data)//第一步:创建新结点
{
	LinkList* newNode = (LinkList*)malloc(sizeof(LinkList));
	if (newNode == NULL)
	{
		printf("内存分配失败\n");
		exit(1);
	}
	newNode->data = data;  //赋值
	newNode->next = NULL;  //next域置空
	return newNode;
}
//在链表末尾添加结点
void appendNode(LinkList*& head, ElemType data)  //调用的时候写的是appendNode(&head,data)
{
	LinkList* newNode = createNode(data);
	if (head->next == NULL)
	{
		head->next = newNode;
		return;
	}
	LinkList* temp = head;
	while (temp->next != NULL)
	{
		temp = temp->next;
	}
	temp->next = newNode;

}
void PrintList(LinkList*& L)   //输出链表中的元素
{
	LinkList* p = L;
	printf("链表中的元素有:");
	while (p->next != NULL)
	{
		printf("%d\t", p->next->data);
		p = p->next;
	}
	printf("\n");
}
void DestroyList(LinkList*& L)//销毁单链表
{
	LinkList* pre = L, * p = L->next;
	while (p != NULL)
	{
		free(pre);
		pre = p;
		p = p->next;
	}
	free(pre);//循环结束时,p为NULL,pre指向尾结点,释放它
}
/*****************************************************************//**
 * 已知带头结点的单链表L,设计一个算法,以单链表的首结点值x为基准,
 * 将该单链表分割为两个部分,使所有小于x的结点排在大于或等于x的结点之前。
 * 例如,原链表为(3,5,4,1,2),完成该算法后链表为(2,1,3,5,4)。
 * 要求空间复杂度为O(1)。(可以用头插法或者交换)
 *********************************************************************/
void DevideL(LinkList*& L, int x)//
{
	if (L->next == NULL || L->next->next == NULL)
	{  //如果为空链表或只有一个数据结点的话则结束
		return;
	}
	//一开始用front来保存第一个数据结点,若有后面的数据插上来则front指向这个新插上来的数据结点
	LinkList* front=L->next;
	//设置一个rear指针指向开始往下轮着处理完的链表的尾部,比如3,5,4,1,2
	// 处理完3和5,则rear指向5这个结点
	LinkList* rear=L;//一定要注意一开始时rear是指向头结点的!
	//temp1指针用来指向要处理的结点,一开始是第一个数据结点,一般在rear指针的后面
	LinkList* temp1 = L->next;
	LinkList* temp2;//temp2用于暂存temp1的下一个结点
	while (temp1 != NULL)
	{
		
		if (temp1->data < x)
		{
			temp2 = temp1->next;
			rear->next = temp1->next;
			temp1->next = front;
			front = temp1;
			temp1 = temp2;
		}
		else
		{
			temp1 = temp1->next;
			rear = rear->next;//尾指针往后移动一位
		}
	}
	L->next = front;//将分割好的链表接回到头结点的后面
}
int main(int argc, char* argv[])
{
	LinkList* L;
	InitList(L);
	appendNode(L, 3);
	appendNode(L, 5);
	appendNode(L, 4);
	appendNode(L, 1);
	appendNode(L, 2);
	printf("分割前");
	PrintList(L);
	DevideL(L, 3);
	printf("分割后");
	PrintList(L);
	DestroyList(L);
	return 0;
}



在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值