0
点赞
收藏
分享

微信扫一扫

【CSS】倾斜按钮

Java架构领域 2023-08-05 阅读 76

前言

上一章,我们讲了数据结构--动态顺序表,我们会发现有以下问题:

下面我们来看看单链表这种线性结构;


链表

概念与结构

链表是一种常见的数据结构,用于存储和组织数据。它由一系列节点组成,每个节点包含两部分:数据和指向下一个节点的指针

链表中的节点在内存中可以分布在任意位置,不像数组那样需要连续的存储空间。每个节点都包含了存储的数据以及指向下一个节点的指针。通过这种方式,链表可以灵活地分配和管理内存空间。就像一节节连动的火车车厢;

 在数据结构中,呈现:

 逻辑图中,呈现:

 在逻辑图中,链式结构是连续性的,但实际上不一样连续;从数据结构中看出,链表是通过地址来联系在一起的,不需要地址的连续性;在我们要解决链表相关问题时,只需要画出逻辑图即可

链表的分类

实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:

1. 单向或者双向

2. 带头或者不带头
 

3. 循环或者非循环
 

可以通过一定的组合达成不同种类的链表;

这里我们比较常用的是有两种结构:

 

 在这里,我们将先实现无头单向非循环链表,这是链表中结构最为简单的;简称单链表。


单链表的接口实现

先写一下它的结构:

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

typedef int SLTDataType;
typedef struct SLTNode
{
	SLTDataType data;
	struct SListNode* next;
	
}SLTNode;

单链表打印

void SLTrint(SLTNode* phead)
{
	SLTNode* cur = phead;
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

增加链表结点

SLTNode* BuySListNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror("mallco fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;

	return newnode;
}

尾插

void SLPushBack(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = BuySListNode(x);
	if (* pphead == NULL)
	{
		* pphead = newnode;
	}
	else
	{
		SLTNode* tail = * pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}

		tail->next = newnode;
	}
	
}

验证:

void Test3()
{
	SLTNode* plist = NULL;
	SLPushBack(&plist, 1);
	SLPushBack(&plist, 2);
	SLPushBack(&plist, 3);
	SLPushBack(&plist, 4);
	SLTrint(plist);
	
}
int main()
{
	Test3();
	return 0;
}

 尾删

void SLPopBack(SLTNode** pphead)
{
	assert(pphead);
	//判空
	assert(*pphead);
	//一个节点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	//其他
	else
	{
		SLTNode* tailPrev = NULL;
		SLTNode* tail = *pphead;
		while (tail->next)
		{
			tailPrev = tail;
			tail = tail->next;
		}
		free(tail);
		tailPrev->next = NULL;

	}
}

验证:

void Test3()
{
	SLTNode* plist = NULL;
	SLPushBack(&plist, 1);
	SLPushBack(&plist, 2);
	SLPushBack(&plist, 3);
	SLPushBack(&plist, 4);
	SLTrint(plist);
	SLPopBack(&plist);
	SLTrint(plist);
	
}
int main()
{
	Test3();
	return 0;
}

 头插头删

void SLPushFront(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = BuySListNode(x);
	
	newnode->next = *pphead;
	*pphead = newnode;

}

void SLPopFront(SLTNode** pphead)
{	
	assert(pphead);
	//判空
	assert(*pphead);
	//其他
	SLTNode* newhead = (*pphead)->next;
	free(*pphead);
	*pphead = newhead;
}

验证:

void Test2()
{
	SLTNode* plist = NULL;
	SLPushBack(&plist, 1);
	SLPushBack(&plist, 2);
	SLPushBack(&plist, 3);
	SLPushBack(&plist, 4);
	SLPushBack(&plist, 5);
	SLTrint(plist);
	SLPushFront(&plist, 6);
	SLPushFront(&plist, 7);
	SLPushFront(&plist, 8);
	SLPushFront(&plist, 9);
	SLTrint(plist);
	SLPopFront(&plist);
	SLTrint(plist);

}


int main()
{
	Test2();
	return 0;
}

 查找与插入

SLTNode* SLFind(SLTNode* phead, SLTDataType x)
{
	//判空
	assert(phead);
	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);
	SLTNode* newnode = BuySListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
	
}

验证:

void Test3()
{
	SLTNode* plist = NULL;
	SLPushBack(&plist, 1);
	SLPushBack(&plist, 2);
	SLPushBack(&plist, 3);
	SLPushBack(&plist, 4);
	SLTrint(plist);
	SLTNode* pos = SLFind(plist, 3);
	SLTInsertAfter(pos, 88);
	SLTrint(plist);

}
int main()
{
	Test3();
	return 0;
}

删除pos结点

void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pos);
	if (pos == *pphead)
	{
		SLPopFront(pphead);
	}
	else
	{
		SLTNode* perv = *pphead;
		while (perv->next != pos)
		{
			perv = perv->next;
		}
		perv->next = pos->next;
		free(pos);
	}
}

void SLTEraseAfter(SLTNode* pos)
{
	assert(pos);
	//检查尾节点
	assert(pos->next);

	SLTNode* posNext = pos->next;

	pos->next = posNext->next;
	free(posNext);

}

验证:

void Test3()
{
	SLTNode* plist = NULL;
	SLPushBack(&plist, 1);
	SLPushBack(&plist, 2);
	SLPushBack(&plist, 3);
	SLPushBack(&plist, 4);
	SLTrint(plist);
	SLTNode* pos = SLFind(plist, 3);
	SLTInsertAfter(pos, 88);
	SLTrint(plist);
	SLTErase(&plist, pos);
	SLTrint(plist);
	
}
int main()
{
	Test3();
	return 0;
}

 

void Test3()
{
	SLTNode* plist = NULL;
	SLPushBack(&plist, 1);
	SLPushBack(&plist, 2);
	SLPushBack(&plist, 3);
	SLPushBack(&plist, 4);
	SLTrint(plist);
	SLTNode* pos = SLFind(plist, 3);
	SLTInsertAfter(pos, 88);
	SLTrint(plist);
	SLTEraseAfter(pos);
	SLTrint(plist);
	
}
int main()
{
	Test3();
	return 0;
}

 摧毁

void SLTDestroy(SLTNode** pphead)
{
	assert(pphead);
	SLTNode* cur = *pphead;
	while (cur)
	{
		SLTNode* prev = cur;
		cur = cur->next;
		free(prev);
	}
	*pphead = NULL;
}

验证:

void Test3()
{
	SLTNode* plist = NULL;
	SLPushBack(&plist, 1);
	SLPushBack(&plist, 2);
	SLPushBack(&plist, 3);
	SLPushBack(&plist, 4);
	SLTrint(plist);
	SLTNode* pos = SLFind(plist, 3);
	SLTInsertAfter(pos, 88);
	SLTrint(plist);
	SLTDestroy(&plist);
	SLTrint(plist);
}
int main()
{
	Test3();
	return 0;
}

 完整代码

slist.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

typedef int SLTDataType;
typedef struct SLTNode
{
	SLTDataType data;
	struct SListNode* next;
	
}SLTNode;


void SLTrint(SLTNode* phead);
SLTNode* BuySListNode(SLTDataType x);
void SLPushBack(SLTNode** pphead, SLTDataType x);
void SLPushFront(SLTNode** pphead, SLTDataType x);
void SLPopBack(SLTNode** pphead);
void SLPopFront(SLTNode** pphead);
SLTNode* SLFind(SLTNode* phead, SLTDataType x);
void SLTInsertAfter(SLTNode* pos, SLTDataType x);
void SLTErase(SLTNode** pphead, SLTNode* pos);
void SLTEraseAfter(SLTNode* pos);
void SLTDestroy(SLTNode** phead);

slist.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include"Slist.h"

void SLTrint(SLTNode* phead)
{
	SLTNode* cur = phead;
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

SLTNode* BuySListNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror("mallco fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;

	return newnode;
}


void SLPushBack(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = BuySListNode(x);
	if (* pphead == NULL)
	{
		* pphead = newnode;
	}
	else
	{
		SLTNode* tail = * pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}

		tail->next = newnode;
	}
	
}

void SLPushFront(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = BuySListNode(x);
	
	newnode->next = *pphead;
	*pphead = newnode;

}

void SLPopBack(SLTNode** pphead)
{
	assert(pphead);
	//判空
	assert(*pphead);
	//一个节点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	//其他
	else
	{
		SLTNode* tailPrev = NULL;
		SLTNode* tail = *pphead;
		while (tail->next)
		{
			tailPrev = tail;
			tail = tail->next;
		}
		free(tail);
		tailPrev->next = NULL;

	}
}
void SLPopFront(SLTNode** pphead)
{	
	assert(pphead);
	//判空
	assert(*pphead);
	//其他
	SLTNode* newhead = (*pphead)->next;
	free(*pphead);
	*pphead = newhead;
}

SLTNode* SLFind(SLTNode* phead, SLTDataType x)
{
	//判空
	assert(phead);
	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);
	SLTNode* newnode = BuySListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
	
}

void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pos);
	if (pos == *pphead)
	{
		SLPopFront(pphead);
	}
	else
	{
		SLTNode* perv = *pphead;
		while (perv->next != pos)
		{
			perv = perv->next;
		}
		perv->next = pos->next;
		free(pos);
	}
}

void SLTEraseAfter(SLTNode* pos)
{
	assert(pos);
	//检查尾节点
	assert(pos->next);

	SLTNode* posNext = pos->next;

	pos->next = posNext->next;
	free(posNext);

}

void SLTDestroy(SLTNode** pphead)
{
	assert(pphead);
	SLTNode* cur = *pphead;
	while (cur)
	{
		SLTNode* prev = cur;
		cur = cur->next;
		free(prev);
	}
	*pphead = NULL;
}

test.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include"Slist.h"

void Test1()
{
	int n;
	SLTNode* plist = NULL;
	printf("请输入链表长度");
	scanf("%d", &n);
	printf("请输入值");
	for (int i = 0; i < n; i++)
	{
		int val;
		scanf("%d", &val);
		SLTNode* newnode = BuySListNode(val);

		newnode->next = plist;
		plist = newnode;
	}
	SLTrint(plist);
}

void Test2()
{
	SLTNode* plist = NULL;
	SLPushBack(&plist, 1);
	SLPushBack(&plist, 2);
	SLPushBack(&plist, 3);
	SLPushBack(&plist, 4);
	SLPushBack(&plist, 5);
	SLTrint(plist);
	SLPushFront(&plist, 6);
	SLPushFront(&plist, 7);
	SLPushFront(&plist, 8);
	SLPushFront(&plist, 9);
	SLTrint(plist);
	SLPopFront(&plist);
	SLTrint(plist);

}

void Test3()
{
	SLTNode* plist = NULL;
	SLPushBack(&plist, 1);
	SLPushBack(&plist, 2);
	SLPushBack(&plist, 3);
	SLPushBack(&plist, 4);
	SLTrint(plist);
	SLTNode* pos = SLFind(plist, 3);
	SLTInsertAfter(pos, 88);
	SLTrint(plist);
	SLTDestroy(&plist);
	SLTrint(plist);
}
int main()
{
	Test3();
	return 0;
}
举报

相关推荐

0 条评论