无头节点--单链表

目录

一、单链表打印:

 二、增容

三、单链表尾插

四、单链表头插

五、单链表尾删

六、单链表头删

七、单链表的查找

八、单链表在pos之后插入X

九、单链表在pos之前插入X

十、删除pos位置

十一、删除pos之后的位置

十二、销毁链表

总代码:

Slistexe.h

Slistexe.c

test.c

 部分运行结果:​


一、单链表打印:

//打印
void SListprint(SL* phead)
{
	SL* cur = phead;
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

 二、增容

//增容
struct SListNode* SListBuyNode(DataType x)
{
	//创建一个节点
	struct SListNode* newnode = (struct SListNode*)malloc(sizeof(struct SListNode));
	if (newnode == NULL)
	{
		printf("malloc failed\n");
		exit(-1);
	}
	newnode->next = NULL;
	newnode->data = x;
}

三、单链表尾插

//单链表尾插
void SListPushBack(SL** phead,DataType x)
{
	assert(phead);//检查头指针的地址是否为空
	//如果头指针为空,那么就新建一个节点
	struct SListNode* newnode = SListBuyNode(x);
	//如果头指针指向NULL的情况
	if(*phead == NULL)
	{
		//进行增容
		*phead = newnode;
	}
	//如果头指针不指向NULL的情况
	else
	{
		//寻找到尾部,再尾部将值插入
		SL* cur = *phead;
		while (cur->next != NULL)
		{
			cur = cur->next;
		}
		//将新建节点链接到尾节点后面
		cur->next = SListBuyNode(x);
	}
}

四、单链表头插

//单链表头插
void SListPushFront(SL** phead, DataType x)
{
	assert(phead);
	//如果头指针指向NULL或者不为NULL都可以
	struct SListNode* cur = *phead;
	//创建一个节点
	struct SListNode* newnode = SListBuyNode(x);
	newnode->next = cur;
	*phead = newnode;
}

五、单链表尾删

分为三种情况:头指针指向NULL,只有一个节点,有多个多个节点

//单链表尾删
void SListPopBack(SL** phead)
{
	//如果头指针指向NULL
	assert(*phead);

	//如果只有一个节点的问题,尾删
	if ((*phead)->next == NULL)
	{
		free(*phead);
		*phead = NULL;
	}
	else//多个节点的情况
	{
		//寻找尾的前一个和尾
		struct SListNode* tail = *phead;
		struct SListNode* prev = NULL;
		while (tail->next != NULL)
		{
			prev = tail;
			tail = tail->next;
		}
		prev->next = tail->next;
		free(tail);
		tail = NULL;
	}
}

六、单链表头删

//单链表头删
void SListPopFront(SL** phead)
{
	assert(phead);
	//如果头指针指向NULL
	assert(*phead);
	//如果只有一个节点和多个节点的情况
	SL* cur = *phead;
	*phead = cur->next;
	free(cur);
	cur = NULL;
}

七、单链表的查找

//单链表的查找
SL* SListFind(SL* phead,DataType x)
{
	SL* tail = phead;
	//从头找到尾
	while (tail)
	{
		if (tail->data == x)
		{
			return tail;
		}
		tail = tail->next;
	}
	//没找到
	return NULL;
}

八、单链表在pos之后插入X

//单链表在pos之后插入X
void SListPosAfter(SL* pos,DataType x)
{
	//创建一个新节点
	struct SListNode* newnode = SListBuyNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

九、单链表在pos之前插入X
 

void SListPosPrev(SL** phead,SL* pos,DataType x)
{
	assert(phead);
	//pos的位置不能NULL
	assert(pos);
	//创建一个新节点
	struct SListNode* newnode = SListBuyNode(x);
	
	//如果pos指向NULL的情况,也就是pos == *phead
	if (pos == *phead)
	{
		*phead = newnode;
		(*phead)->next = pos;
	}
	else//多个节点的情况
	{
		SL* cur = *phead;
		SL* prev = NULL;
		//要找到pos前一个位置
		while (cur != pos)
		{
			prev = cur;
			cur = cur->next;
		}
		newnode->next = pos;
		prev->next = newnode;
	}
}

十、删除pos位置

//删除pos位置
void SListErase(SL** phead,SL* pos)
{
	assert(pos);
	assert(phead);
	//如果只有一个节点pos == *phead
	if (pos == *phead)
	{
		*phead = pos->next;
		free(pos);
		pos = NULL;
	}
	else
	{
		//多个节点的情况
		SL* cur = *phead;
		SL* prev = NULL;
		//要找到pos前一个位置
		while (cur != pos)
		{
			prev = cur;
			cur = cur->next;
		}
		prev->next = pos->next;
		free(pos);
		pos = NULL;
	}
}

十一、删除pos之后的位置

//删除pos之后的位置
void SListEraseAfter(SL* pos)
{
	assert(pos && pos->next);//pos位置不为NULL,并且pos后面的位置不为NULL,才能删除pos后面的位置
	SL* PosAfter = pos->next;
	pos->next = PosAfter->next;
	free(PosAfter);
	PosAfter = NULL;
}

十二、销毁链表

//销毁链表
void SListDestory(SL** phead)
{
	SL* tail = *phead;
	while (tail)
	{
		tail = tail->next;
		free(*phead);
		*phead = tail;
	}
}

总代码:

Slistexe.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int DataType;
typedef struct SListNode
{
	DataType data;
	struct SListNode* next;
}SL;

//单链表打印
void SListprint(SL* ps);
//单链表尾插
void SListPushBack(SL** ps,int x);
//单链表头插
void SListPushFront(SL** phead, int x);
//单链表头删
void SListPopFront(SL** phead);
//单链表头删
void SListPopFront(SL** phead);
//单链表的查找
SL* SListFind(SL* phead, DataType x);
//单链表在pos之后插入X
void SListPosAfter(SL* pos, DataType x);
//单链表在pos之前插入X
void SListPosPrev(SL** phead, SL* pos, DataType x);
//删除pos位置
void SListErase(SL** phead, SL* pos);
//删除pos之后的位置
void SListEraseAfter(SL* pos);
//销毁链表
void SListDestory(SL** phead);

Slistexe.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SListexe.h"
//增容
struct SListNode* SListBuyNode(DataType x)
{
	//创建一个节点
	struct SListNode* newnode = (struct SListNode*)malloc(sizeof(struct SListNode));
	if (newnode == NULL)
	{
		printf("malloc failed\n");
		exit(-1);
	}
	newnode->next = NULL;
	newnode->data = x;
}

//打印
void SListprint(SL* phead)
{
	SL* cur = phead;
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

//单链表尾插
void SListPushBack(SL** phead,DataType x)
{
	assert(phead);//检查头指针的地址是否为空
	//如果头指针为空,那么就新建一个节点
	struct SListNode* newnode = SListBuyNode(x);
	//如果头指针指向NULL的情况
	if(*phead == NULL)
	{
		//进行增容
		*phead = newnode;
	}
	//如果头指针不指向NULL的情况
	else
	{
		//寻找到尾部,再尾部将值插入
		SL* cur = *phead;
		while (cur->next != NULL)
		{
			cur = cur->next;
		}
		//将新建节点链接到尾节点后面
		cur->next = SListBuyNode(x);
	}
}
//单链表头插
void SListPushFront(SL** phead, DataType x)
{
	assert(phead);
	//如果头指针指向NULL或者不为NULL都可以
	struct SListNode* cur = *phead;
	//创建一个节点
	struct SListNode* newnode = SListBuyNode(x);
	newnode->next = cur;
	*phead = newnode;
}
//单链表尾删
void SListPopBack(SL** phead)
{
	//如果头指针指向NULL
	assert(*phead);

	//如果只有一个节点的问题,尾删
	if ((*phead)->next == NULL)
	{
		free(*phead);
		*phead = NULL;
	}
	else//多个节点的情况
	{
		//寻找尾的前一个和尾
		struct SListNode* tail = *phead;
		struct SListNode* prev = NULL;
		while (tail->next != NULL)
		{
			prev = tail;
			tail = tail->next;
		}
		prev->next = tail->next;
		free(tail);
		tail = NULL;
	}
}
//单链表头删
void SListPopFront(SL** phead)
{
	assert(phead);
	//如果头指针指向NULL
	assert(*phead);
	//如果只有一个节点和多个节点的情况
	SL* cur = *phead;
	*phead = cur->next;
	free(cur);
	cur = NULL;
}
//单链表的查找
SL* SListFind(SL* phead,DataType x)
{
	SL* tail = phead;
	//从头找到尾
	while (tail)
	{
		if (tail->data == x)
		{
			return tail;
		}
		tail = tail->next;
	}
	//没找到
	return NULL;
}
//单链表在pos之后插入X
void SListPosAfter(SL* pos,DataType x)
{
	//创建一个新节点
	struct SListNode* newnode = SListBuyNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}
//单链表在pos之前插入X
void SListPosPrev(SL** phead,SL* pos,DataType x)
{
	assert(phead);
	//pos的位置不能NULL
	assert(pos);
	//创建一个新节点
	struct SListNode* newnode = SListBuyNode(x);
	
	//如果pos指向NULL的情况,也就是pos == *phead
	if (pos == *phead)
	{
		*phead = newnode;
		(*phead)->next = pos;
	}
	else//多个节点的情况
	{
		SL* cur = *phead;
		SL* prev = NULL;
		//要找到pos前一个位置
		while (cur != pos)
		{
			prev = cur;
			cur = cur->next;
		}
		newnode->next = pos;
		prev->next = newnode;
	}
}

//删除pos位置
void SListErase(SL** phead,SL* pos)
{
	assert(pos);
	assert(phead);
	//如果只有一个节点pos == *phead
	if (pos == *phead)
	{
		*phead = pos->next;
		free(pos);
		pos = NULL;
	}
	else
	{
		//多个节点的情况
		SL* cur = *phead;
		SL* prev = NULL;
		//要找到pos前一个位置
		while (cur != pos)
		{
			prev = cur;
			cur = cur->next;
		}
		prev->next = pos->next;
		free(pos);
		pos = NULL;
	}
}
//删除pos之后的位置
void SListEraseAfter(SL* pos)
{
	assert(pos && pos->next);//pos位置不为NULL,并且pos后面的位置不为NULL,才能删除pos后面的位置
	SL* PosAfter = pos->next;
	pos->next = PosAfter->next;
	free(PosAfter);
	PosAfter = NULL;
}
//销毁链表
void SListDestory(SL** phead)
{
	SL* tail = *phead;
	while (tail)
	{
		tail = tail->next;
		free(*phead);
		*phead = tail;
	}
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SListexe.h"
void test1()
{
	SL* s1 = NULL;//初始化
	//SListPushBack(&s1,1);
	//SListPushBack(&s1, 2);
	//SListPushBack(&s1, 3);
	SListPushFront(&s1,4);
	SListPushFront(&s1, 3);
	/*SListprint(s1);*/
	/*SListPushFront(&s1, 4);*/
	//SListPopFront(&s1);
	//SListPopFront(&s1);
	
	SL* pos = SListFind(s1,3);
	if (pos)
	{
		SListPosAfter(pos,20);
		SListPosPrev(&s1,pos,30);
		/*SListErase(&s1,pos);*/
		/*printf("%d",pos->data);*/
		SListEraseAfter(pos);
	}
	SListprint(s1);
}
int main()
{
	test1();
}

 部分运行结果:

本篇为无头结点单链表篇,如有问题,请大家在评论区多多评论,共同学习O(∩_∩)O

### 回答1: 以下是一个示例无头节点单链表代码,包括节点的定义、插入、删除、查找和输出操作: ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next class LinkedList: def __init__(self): self.head = None def insert(self, val): new_node = ListNode(val) new_node.next = self.head self.head = new_node def delete(self, val): prev = None curr = self.head while curr is not None and curr.val != val: prev = curr curr = curr.next if curr is not None: if prev is None: self.head = curr.next else: prev.next = curr.next def search(self, val): curr = self.head while curr is not None and curr.val != val: curr = curr.next return curr def print_list(self): curr = self.head while curr is not None: print(curr.val, end=' ') curr = curr.next print() ``` 在这个代码中,节点使用 `ListNode` 类来表示,每个节点包括一个值和一个指向下一个节点的指针。链表使用 `LinkedList` 类来表示,包括一个头节点 `head`,初始化为 `None`。 `insert` 方法用于在链表头部插入一个新节点,首先创建一个新节点,然后将它的 `next` 指针指向当前的头节点,最后将头节点指向新节点。 `delete` 方法用于从链表中删除一个值为 `val` 的节点,首先遍历整个链表找到要删除的节点,然后修改它前面节点的 `next` 指针即可。需要注意的是,如果要删除的节点是头节点,需要特殊处理。 `search` 方法用于在链表中查找一个值为 `val` 的节点,遍历整个链表即可。 `print_list` 方法用于按顺序输出整个链表中的节点值。 ### 回答2: 无头节点单链表是指链表中没有一个特定的头节点,而是通过记录链表的第一个节点来代表整个链表的首部。下面是一个示例的无头节点单链表的代码实现: ```python class ListNode: def __init__(self, value): self.value = value self.next = None class LinkedList: def __init__(self): self.head = None def is_empty(self): return self.head is None def insert(self, value): new_node = ListNode(value) if self.is_empty(): self.head = new_node else: current = self.head while current.next: current = current.next current.next = new_node def delete(self, value): if self.is_empty(): return if self.head.value == value: self.head = self.head.next return current = self.head while current.next: if current.next.value == value: current.next = current.next.next return current = current.next def search(self, value): if self.is_empty(): return False current = self.head while current: if current.value == value: return True current = current.next return False ``` 以上是无头节点单链表的基本操作代码。链表包含两个类,ListNode 表示链表节点,LinkedList 表示链表本身。其中,insert 方法用于插入节点到链表尾部,delete 方法用于删除指定值的节点,search 方法用于查找链表中是否存在指定值的节点。 ### 回答3: 无头节点单链表是指链表中没有头节点,只有数据节点。在这种情况下,我们需要自己实现链表的插入、删除、查找等操作。 定义一个节点类,用来表示链表的节点,该节点包含两个属性:数据和下一个节点的指针。 ```python class Node: def __init__(self, data=None): self.data = data self.next = None ``` 接下来,我们定义一个LinkedList类,该类包含一些对链表进行操作的方法。 ```python class LinkedList: def __init__(self): self.head = None def insert(self, data): new_node = Node(data) if self.head is None: self.head = new_node else: current = self.head while current.next is not None: current = current.next current.next = new_node def delete(self, data): if self.head is None: return if self.head.data == data: self.head = self.head.next return current = self.head while current.next is not None: if current.next.data == data: current.next = current.next.next return current = current.next def search(self, data): current = self.head while current is not None: if current.data == data: return True current = current.next return False def display(self): current = self.head while current is not None: print(current.data, end=" ") current = current.next print() ``` 上述代码中,我们实现了插入、删除、查找和展示链表数据的方法。我们可以通过创建一个LinkedList对象并调用这些方法来操作链表。 需要注意的是,在无头节点单链表中,我们需要特别处理链表的头部插入和删除操作。 这样,我们就完成了一个无头节点单链表的实现。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值