#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;
}
以值为基准分割带头结点的单链表
最新推荐文章于 2024-07-25 14:12:37 发布