二战单链表

本文详细介绍了单链表的内存结构、节点定义以及各种操作,包括尾部删除、头部删除、在特定位置插入和删除,以及链表的创建、打印和查找功能。
摘要由CSDN通过智能技术生成

链表也是一种线性表,适用于需要频繁插入删除数据的情况

链表在逻辑上是连续的,在物理上是不连续的

链表的内存结构是不连续的内存空间,是将一组零散的内存块串联,,每个内存块被称为结点(Node),结点分为两部分:数据域和指针域。

下面实现单链表(不带头)

定义结点

//single list
typedef int SLNDataType;
typedef struct SListNode
{
	SLNDataType val;
	struct SListNode* next;
}SLNode;

删除

尾删

声明

形参是实参的一份临时拷贝,对形参的修改不会影响实参,故这里传二级指针

void SLPopBack(SLNode** pphead);

 实现

void SLPopBack(SLNode** pphead)
{
	if ((*pphead) == NULL)
	{
		return;
	}
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
		return;
	}
	SLNode* prev = NULL;
	SLNode* tail = *pphead;
	while (tail->next!=NULL)
	{
		prev = tail;
		tail = tail->next;
	}
	free(tail);
	tail = NULL;
	prev->next = NULL;
}

第二种方法

void SLPopBackplus(SLNode** pphead)
{
	if ((*pphead) == NULL)
	{
		return;
	}
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
		return;
	}
	SLNode* tail = *pphead;
	while (tail->next->next != NULL)
	{
		tail = tail->next;
	}
	free(tail->next);
	tail->next = NULL;
}

头删

声明

void SLPopFront(SLNode** pphead);

实现

void SLPopFront(SLNode** pphead)
{
	if (*(pphead) == NULL)
	{
		return;
	}
	SLNode* newhead = (*pphead)->next;
	free(*pphead);
	*pphead = newhead;
	return;
}

 在某个位置删除

声明

void SLErase(SLNode** pphead, SLNode* pos);

实现 

void SLErase(SLNode** pphead, SLNode* pos)
{
	if (pos == NULL)
	{
		return;
	}
	if (*pphead == pos)
	{
		*pphead = pos->next;
		free(pos);
		pos = NULL;
		return;
	}
	SLNode* del = *pphead;
	while (del->next!=pos)
	{
		del = del->next;
	}
	del->next = pos->next;
	free(pos);
	pos = NULL;
	return;
}

在某个位置后删除 

声明

void SLTEraseAfter(SLNode* pos);

 实现

void SLTEraseAfter(SLNode* pos)
{
	assert(pos);
	assert(pos->next);
	SLNode* tmp = pos->next;
	pos->next = pos->next->next;
	free(tmp);
	tmp = NULL;
}

 插入

创建新结点函数

SLNode* CreateNode(SLNDataType x)
{
	SLNode* newNode=(SLNode*)malloc(sizeof(SLNDataType));
	if (newNode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newNode->val = x;
	newNode->next = NULL;
	return newNode;
}

尾插

声明

void SLPushBack(SLNode** pphead, SLNDataType x);

实现

void SLPushBack(SLNode** pphead, SLNDataType x)
{
	SLNode* newNode = CreateNode(x);
	if (*pphead == NULL)
	{
		*pphead = newNode;  //改变结构体的指针,用二级指针
	}
	else
	{
		SLNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;   
		}
		tail->next = newNode;   //改变结构体,用结构体指针
	}
}

头插

声明

void SLPushFront(SLNode** pphead, SLNDataType x);

实现 

void SLPushFront(SLNode** pphead, SLNDataType x)
{
	SLNode* newNode = CreateNode(x);
	newNode->next = *pphead;
	*pphead = newNode;
}

 在某个位置前插入

声明

void SLInsert(SLNode** pphead, SLNode* pos, SLNDataType x);

实现 

void SLInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
{
	if (*pphead == pos)
	{
		SLNode* newNode = CreateNode(x);
		newNode->next = *pphead;
		*pphead = newNode;
		return;
	}
	SLNode* prev = *pphead;
	while (prev->next != pos)
	{
		prev = prev->next;
	}
	SLNode* newNode = CreateNode(x);
	newNode->next = pos;
	prev->next = newNode;
}

 在某个位置后插入

声明

void SLTInsertAfter(SLNode * pos, SLNDataType x);

实现 

void SLTInsertAfter(SLNode * pos, SLNDataType x)
{
	assert(pos);
	SLNode* newnode = CreateNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

打印

声明

void SLprint(SLNode* head);

 实现

void SLprint(SLNode* head)
{
	SLNode* cur = head;
	if (cur == NULL)
	{
		printf("NULL\n");
		return;
	}
	while (cur->next != NULL)
	{
		printf("%d->", cur->val);
		cur = cur->next;
	}
	printf("%d->NULL\n", cur->val);
}

查找

声明

SLNode* SLFind(SLNode* phead,SLNDataType x);

实现

SLNode* SLFind(SLNode* phead,SLNDataType x)
{

	while (phead != NULL&&phead->val != x)
	{
		phead = phead->next;
	}
	if (phead == NULL)
	{
		printf("查找失败\n");
		return NULL;
	}
	else
	{
		printf("查找成功\n");
		return phead;
	}
}

销毁

声明

void SLDestroy(SLNode** pphead);

实现

void SLDestroy(SLNode** pphead)
{
	SLNode* des=(*pphead)->next;
	while (des&&*pphead)
	{
		free(*pphead);
		*pphead = des;
		des = des->next;
	}
	free(*pphead);
	*pphead = NULL;
	return;
}

是不是名表其意呢(不带头可能就真的跟不带头一样难),测试下来快崩溃了,感觉不带头的比带头的难好多的说(指针妹学好)

完整代码

SList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//single list
typedef int SLNDataType;
typedef struct SListNode
{
	SLNDataType val;
	struct SListNode* next;
}SLNode;
void SLprint(SLNode* head);

void SLPushFront(SLNode** pphead, SLNDataType x);
void SLPushBack(SLNode** pphead, SLNDataType x);

void SLPopBack(SLNode** pphead);
void SLPopBackplus(SLNode** pphead);
void SLPopFront(SLNode** pphead);

SLNode* SLFind(SLNode* phead,SLNDataType x);

//在pos前插入
void SLInsert(SLNode** pphead,SLNode* pos, SLNDataType x);
//删除pos位置
void SLErase(SLNode** pphead,SLNode* pos);

// 后面插入 后面删除
void SLTInsertAfter(SLNode* pos, SLNDataType x);
void SLTEraseAfter(SLNode* pos);

void SLDestroy(SLNode** pphead);

SList.c

#include"SList.h"
void SLprint(SLNode* head)
{
	SLNode* cur = head;
	if (cur == NULL)
	{
		printf("NULL\n");
		return;
	}
	while (cur->next != NULL)
	{
		printf("%d->", cur->val);
		cur = cur->next;
	}
	printf("%d->NULL\n", cur->val);
}
SLNode* CreateNode(SLNDataType x)
{
	SLNode* newNode=(SLNode*)malloc(sizeof(SLNDataType));
	if (newNode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newNode->val = x;
	newNode->next = NULL;
	return newNode;
}

void SLPushBack(SLNode** pphead, SLNDataType x)
{
	SLNode* newNode = CreateNode(x);
	if (*pphead == NULL)
	{
		*pphead = newNode;  //改变结构体的指针,用二级指针
	}
	else
	{
		SLNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;   
		}
		tail->next = newNode;   //改变结构体,用结构体指针
	}
}
void SLPushFront(SLNode** pphead, SLNDataType x)
{
	SLNode* newNode = CreateNode(x);
	newNode->next = *pphead;
	*pphead = newNode;
}
void SLPopBack(SLNode** pphead)
{
	if ((*pphead) == NULL)
	{
		return;
	}
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
		return;
	}
	SLNode* prev = NULL;
	SLNode* tail = *pphead;
	while (tail->next!=NULL)
	{
		prev = tail;
		tail = tail->next;
	}
	free(tail);
	tail = NULL;
	prev->next = NULL;
}
void SLPopBackplus(SLNode** pphead)
{
	if ((*pphead) == NULL)
	{
		return;
	}
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
		return;
	}
	SLNode* tail = *pphead;
	while (tail->next->next != NULL)
	{
		tail = tail->next;
	}
	free(tail->next);
	tail->next = NULL;
}
void SLPopFront(SLNode** pphead)
{
	if (*(pphead) == NULL)
	{
		return;
	}
	SLNode* newhead = (*pphead)->next;
	free(*pphead);
	*pphead = newhead;
	return;
}
SLNode* SLFind(SLNode* phead,SLNDataType x)
{

	while (phead != NULL&&phead->val != x)
	{
		phead = phead->next;
	}
	if (phead == NULL)
	{
		printf("查找失败\n");
		return NULL;
	}
	else
	{
		printf("查找成功\n");
		return phead;
	}
}
void SLInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
{
	if (*pphead == pos)
	{
		SLNode* newNode = CreateNode(x);
		newNode->next = *pphead;
		*pphead = newNode;
		return;
	}
	SLNode* prev = *pphead;
	while (prev->next != pos)
	{
		prev = prev->next;
	}
	SLNode* newNode = CreateNode(x);
	newNode->next = pos;
	prev->next = newNode;
}
void SLErase(SLNode** pphead, SLNode* pos)
{
	if (pos == NULL)
	{
		return;
	}
	if (*pphead == pos)
	{
		*pphead = pos->next;
		free(pos);
		pos = NULL;
		return;
	}
	SLNode* del = *pphead;
	while (del->next!=pos)
	{
		del = del->next;
	}
	del->next = pos->next;
	free(pos);
	pos = NULL;
	return;
}
void SLDestroy(SLNode** pphead)
{
	SLNode* des=(*pphead)->next;
	while (des&&*pphead)
	{
		free(*pphead);
		*pphead = des;
		des = des->next;
	}
	free(*pphead);
	*pphead = NULL;
	return;
}
void SLTEraseAfter(SLNode* pos)
{
	assert(pos);
	assert(pos->next);
	SLNode* tmp = pos->next;
	pos->next = pos->next->next;
	free(tmp);
	tmp = NULL;
}
void SLTInsertAfter(SLNode * pos, SLNDataType x)
{
	assert(pos);
	SLNode* newnode = CreateNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

test.c

#include"SList.h"
void Test1()
{
	SLNode* s1=NULL;
	SLPushBack(&s1,1);
	SLPushBack(&s1,2);
	SLPushBack(&s1,3);
	SLPushBack(&s1,4);
	SLprint(s1);
	return;
}
void Test2()
{
	SLNode* s1 = NULL;
	SLPushFront(&s1, 1);
	SLPushFront(&s1, 2);
	SLPushFront(&s1, 3);
	SLPushFront(&s1, 4);
	SLprint(s1);
	return;
}
void Test3()
{
	SLNode* s1 = NULL;
	SLPushFront(&s1, 1);
	SLPushFront(&s1, 2);
	SLPushFront(&s1, 3);
	SLPushFront(&s1, 4);
	SLprint(s1);
	SLPopBack(&s1);
	SLprint(s1);
	SLPopBack(&s1);
	SLprint(s1);
	SLPopBack(&s1);
	SLprint(s1);
	SLPopBack(&s1);
	SLprint(s1);
	SLPopBack(&s1);
	SLprint(s1);
	return;
}
void Test4()
{
	SLNode* s1 = NULL;
	SLPushFront(&s1, 1);
	SLPushFront(&s1, 2);
	SLPushFront(&s1, 3);
	SLPushFront(&s1, 4);
	SLprint(s1);
	SLPopBackplus(&s1);
	SLprint(s1);
	SLPopBackplus(&s1);
	SLprint(s1);
	SLPopBackplus(&s1);
	SLprint(s1);
	SLPopBackplus(&s1);
	SLprint(s1);
	SLPopBackplus(&s1);
	SLprint(s1);
	return;
}
void Test5()
{
	SLNode* s1 = NULL;
	SLPushFront(&s1, 1);
	SLPushFront(&s1, 2);
	SLPushFront(&s1, 3);
	SLPushFront(&s1, 4);
	SLprint(s1);
	SLPopFront(&s1);
	SLprint(s1);
	SLPopFront(&s1);
	SLprint(s1);
	SLPopFront(&s1);
	SLprint(s1);
	SLPopFront(&s1);
	SLprint(s1);
	SLPopFront(&s1);
	SLprint(s1);
	return;
}
void Test6()
{
	SLNode* s1 = NULL;
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLprint(s1);
	SLFind(s1, 1);
	SLFind(s1, 5);
	SLFind(s1, 9);
	SLFind(s1, 4);
	return;
}
void Test7()
{
	SLNode* s1 = NULL;
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLprint(s1);
	SLNode* a = SLFind(s1, 1);
	SLInsert(&s1, a , 9);
	SLprint(s1);
	SLNode* b=SLFind(s1, 4);
	SLInsert(&s1, b, 8);
	SLprint(s1);
	return;
}
void Test8()
{
	SLNode* s1 = NULL;
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLprint(s1);
	SLNode* a = SLFind(s1,0 );
	SLErase(&s1, a);
	SLprint(s1);
	SLNode* d = SLFind(s1, 2);
	SLErase(&s1, d);
	SLprint(s1);
	SLNode* b = SLFind(s1, 4);
	SLErase(&s1, b);
	SLprint(s1);
	return;
}
void Test9()
{
	SLNode* s1 = NULL;
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLprint(s1);
	SLDestroy(&s1);
	SLprint(s1);
	return;
}
int main()
{
	Test9();
	return 0;
}

带头的好好写:

#include<stdio.h>
#include<stdlib.h>
//定义单链表
typedef struct Node
{
	int data;
	struct Node* next;
}Node;
//初始化
Node* initList()
{
	Node* list = (Node*)malloc(sizeof(Node));
	list->data = 0;
	list->next = NULL;
	return list;
}
//头插
void headInsert(Node* list, int data)
{
	Node* node = (Node*)malloc(sizeof(Node));
	node->data = data;
	node->next = list->next;
	list->next = node;
	list->data++;
}
//尾插
void tailInsert(Node* list, int data)
{
	Node* head = list;
	Node* node = (Node*)malloc(sizeof(Node));
	node->data = data;
	node->next = NULL;
	list = list->next;
	while (list->next)
	{
		list = list->next;
	}
	list->next = node;
	head->data++;
}
//删除
void delete(Node* list, int data)
{
	Node* pre = list;
	Node* current = list->next;
	while (current)
	{
		if (current->data == data)
		{
			pre->next = current->next;
			free(current);
			current = NULL;
			break;
		}
		pre = current;
		current = current->next;
	}
	list->data--;
}
//遍历
void PrintList(Node* list)
{
	list = list->next;
	while (list)
	{
		printf("%d", list->data);
		list = list->next;
	}
	printf("\n");
}
Node* ReverseList(Node* head)
{
	if (head == NULL)
	{
		return NULL;
	}
	else
	{
		Node* new = head;
 		Node* pre = head;
		while (new->next != NULL)
		{
			new = new->next;
		}
		Node* new1 = new;
		for (int i = 0; i < head->data - 1; i++)
		{
			while (pre->next != new)
			{
				pre = pre->next;
			}
			new->next = pre;
			new = pre;
			pre = head;
		}
		new->next = NULL;
		head->next = NULL;
		pre->next = NULL;
		pre->data = head->data;
		Node* new2 = malloc(sizeof(Node));
		new2->data = head->data;
		new2->next = new1;
		return new2;
	}
}
int main()
{
	Node* list = initList();
	headInsert(list, 1);
	headInsert(list, 2);
	headInsert(list, 3);
	headInsert(list, 4);
	PrintList(list);
	Node* p=ReverseList(list);
	PrintList(p);
}

 

 

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值