顺序表&链表(及其相关代码)

顺序表的本质是数组,它们在内存上是连续存储的。而链表则是由散落的点,通过地址连接起来的链。链表的一个节点分为值域和指针域,值域用于存储当前节点的数值,以单链表为例,指针域存储的是其下一个节点的地址,链表正是以这种方法链接起来的。

顺序表&链表(及其相关代码)_第1张图片

顺序表&链表(及其相关代码)_第2张图片

而顺序表则是一个数组,只不过它会实时记录自己的长度,当长度不够的时候会自动扩容。值得注意的是扩容会有不少的消耗,因此我们每次都会扩容两倍或1.5倍。顺序表的好处是一个动态的数组更方便我们进行广泛的编程,适用性更强,且不会造成过多的空间浪费。

顺序表和链表是两种常见的数据结构,用于存储和管理数据集合。以下是它们的基本概念和主要区别:

  1. 顺序表:

    • 顺序表是一种线性表数据结构,使用一段连续的存储空间来存储数据元素。
    • 通常采用数组来实现顺序表,数据元素的存储位置是连续的,通过索引可以直接访问任意位置的元素。
    • 顺序表的优点包括访问速度快、实现简单,缺点是在插入和删除操作时需要移动大量元素,因此效率较低。
  2. 链表:

    • 链表是一种通过指针链接数据元素的线性表数据结构。
    • 在链表中,每个数据元素称为一个节点,包含数据域和指针域。指针域指向下一个节点,从而将整个链表连接起来。
    • 链表可以分为单向链表、双向链表和循环链表等类型。单向链表只有一个指向下一个节点的指针,双向链表有两个指针分别指向前一个节点和下一个节点,循环链表则将最后一个节点的指针指向第一个节点形成一个环。
    • 链表的优点包括在插入和删除操作时只需要修改指针而不需要移动大量元素,因此效率较高。缺点是通过指针访问元素时需要进行遍历操作,访问速度较慢。

总结:

  • 顺序表和链表都是线性表数据结构,用于存储和管理数据集合。
  • 顺序表使用一段连续的存储空间来存储数据元素,通过索引可以直接访问任意位置的元素。链表通过指针链接数据元素,每个节点包含数据域和指针域。
  • 顺序表的优点包括访问速度快、实现简单,缺点是在插入和删除操作时需要移动大量元素,效率较低。链表的优点是在插入和删除操作时只需要修改指针而不需要移动大量元素,效率较高,缺点是通过指针访问元素时需要进行遍历操作,访问速度较慢。

顺序表&链表(及其相关代码)_第3张图片

接下来我将把顺序表和链表的相关代码贴上去:

顺序表:

头文件:

#pragma once
#include 
#include 
#include 

typedef int SLDateType;
typedef struct SeqList
{
	SLDateType* a;
	int size;
	int capacity;
}SeqList;

// 对数据的管理:增删查改 
void SeqListInit(SeqList* ps);
void SeqListDestroy(SeqList* ps);

void SeqListPrint(SeqList* ps);
void SeqListPushFront(SeqList* ps, SLDateType x);
void SeqListPushBack(SeqList* ps, SLDateType x);
void SeqListPopFront(SeqList* ps);
void SeqListPopBack(SeqList* ps);

// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);

函数实现:

#include "SeqList.h"

void SeqListInit(SeqList* ps)
{
	assert(ps);

	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

void SeqListDestroy(SeqList* ps)
{
	assert(ps);

	if (ps->a != NULL)
	{
		free(ps->a);
		ps->a = NULL;
		ps->size = 0;
		ps->capacity = 0;
	}
}

void SeqListPrint(SeqList* ps)
{
	assert(ps);

	int i = 0;
	for (i = 0; i < ps->size; ++i)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

static void SLCheckCapacity(SeqList* ps)
{
	assert(ps);

	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDateType* tmp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * newcapacity);

		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}

		ps->a = tmp;
		ps->capacity = newcapacity;
	}
}

void SeqListPushFront(SeqList* ps, SLDateType x)
{
	assert(ps);

	SLCheckCapacity(ps);
	int i = 0;
	for (i = ps->size; i >= 0; --i)
	{
		ps->a[i] = ps->a[i - 1];
	}

	ps->a[0] = x;
	ps->size++;
}

void SeqListPushBack(SeqList* ps, SLDateType x)
{
	assert(ps);

	SLCheckCapacity(ps);

	ps->a[ps->size] = x;
	ps->size++;
}

void SeqListPopFront(SeqList* ps)
{
	assert(ps);

	if (ps->size)
	{
		int i = 0;
		for (i = 0; i < ps->size - 1; ++i)
		{
			ps->a[i] = ps->a[i + 1];
		}
		ps->size--;
	}

	return;
}

void SeqListPopBack(SeqList* ps)
{
	assert(ps);

	if (ps->size)
	{
		ps->a[ps->size - 1] = 0;
		ps->size--;
	}

	return;
}

int SeqListFind(SeqList* ps, SLDateType x)
{
	assert(ps);

	int i = 0;
	for (i = 0; i < ps->size; ++i)
	{
		if (ps->a[i] == x)
			return i;
	}
	return -1;
}

void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{
	assert(ps);

	if ((pos >= 0 && pos < ps->size))
	{
		SLCheckCapacity(ps);
		int i = 0;
		for (i = ps->size; i >= pos; --i)
		{
			ps->a[i] = ps->a[i - 1];
		}
		ps->a[pos] = x;
		ps->size++;
	}
	return;
}

void SeqListErase(SeqList* ps, int pos)
{
	assert(ps);

	if (ps->size && (pos>=0 && pos < ps->size))
	{
		int i = 0;
		for (i = pos; i < ps->size - 1; ++i)
		{
			ps->a[i] = ps->a[i + 1];
		}
		ps->size--;
		ps->a[ps->size] = 0;
	}
	return;
}

链表

头文件:

#pragma once
#include 
#include 
#include 

typedef int SLTDateType;

typedef struct SListNode
{
	SLTDateType data;
	struct SListNode* next;
}SListNode;

// 动态申请一个节点
SListNode* BuySListNode(SLTDateType x);
// 单链表打印
void SListPrint(SListNode* plist);
// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType x);
// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType x);
// 单链表的尾删
void SListPopBack(SListNode** pplist);
// 单链表头删
void SListPopFront(SListNode** pplist);
// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x);
// 单链表在pos位置之后插入x
// 分析思考为什么不在pos位置之前插入?
void SListInsertAfter(SListNode** pplist, SListNode** pos, SLTDateType x);
// 单链表删除pos位置之后的值
// 分析思考为什么不删除pos位置?
void SListEraseAfter(SListNode** pplist, SListNode** ppos);

// 在pos的前面插入
void SLTInsert(SListNode** pphead, SListNode** ppos, SLTDateType x);
// 删除pos位置
void SLTErase(SListNode** pplist, SListNode** ppos);
void SLTDestroy(SListNode** pplist);

函数的实现:

#include "SList.h"

// 动态申请一个节点
SListNode* BuySListNode(SLTDateType x)
{
	SListNode* ret = (SListNode*)malloc(sizeof(SListNode));
	if (ret == NULL)
	{
		perror("malloc");
		exit(0);
	}

	ret->data = x;
	ret->next = NULL;

	return ret;
}

// 单链表打印
void SListPrint(SListNode* plist)
{
	if (plist == NULL)
	{
		printf("NULL\n");
		return;
	}

	SListNode* tmp = plist;
	while (tmp)
	{
		printf("%d->", tmp->data);
		tmp = tmp->next;
	}
	printf("NULL\n");
}

// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType x)
{
	assert(pplist);

	SListNode* NewNode = BuySListNode(x);

	if (*pplist == NULL)
	{
		*pplist = NewNode;
	}
	else
	{
		//找尾
		SListNode* tmp = *pplist;
		while (tmp->next)
		{
			tmp = tmp->next;
		}

		tmp->next = NewNode;
	}
}

// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType x)
{
	assert(pplist);

	SListNode* NewNode = BuySListNode(x);
	SListNode* tmp = *pplist;
	*pplist = NewNode;
	NewNode->next = tmp;
}

// 单链表的尾删
void SListPopBack(SListNode** pplist)
{
	assert(pplist);

	if (*pplist == NULL)
		return;

	SListNode* tmp = *pplist;
	SListNode* prev = NULL;

	if (tmp->next == NULL)
	{
		*pplist = NULL;
		free(tmp);
		return;
	}

	//找尾
	while (tmp->next)
	{
		prev = tmp;
		tmp = tmp->next;
	}
	free(tmp);
	(prev->next) = NULL;
}

// 单链表头删
void SListPopFront(SListNode** pplist)
{
	assert(pplist);
	if (*pplist == NULL)
		return;

	SListNode* old_head = *pplist;
	*pplist = (*pplist)->next;
	free(old_head);
}

// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x)
{
	if (plist == NULL)
		return NULL;

	SListNode* tmp = plist;
	while (tmp != NULL)
	{
		if (tmp->data == x)
			return tmp;

		tmp = tmp->next;	
	}

	return NULL;
}

//销毁链表
void SLTDestroy(SListNode** pplist)
{
	assert(pplist);
	if (*pplist == NULL)
		return;

	int count = 1;
	SListNode* tmp = *pplist;

	while (tmp->next)
	{
		tmp = tmp->next;
		count++;
	}

	while (count--)
	{
		SListPopBack(pplist);
	}
}

// 单链表在pos位置之后插入x
void SListInsertAfter(SListNode** pplist, SListNode** ppos, SLTDateType x)
{
	SListNode* NewNode = BuySListNode(x);

	if ((*ppos == NULL) && (*pplist = NULL))
	{
		SListPushFront(pplist, x);
		return;
	}

	SListNode* tmp = *pplist;
	SListNode* after = *pplist;
	while ((tmp->next) != NULL)
	{
		after = tmp->next;
		if (tmp == *ppos)
		{
			((*ppos)->next) = NewNode;
			NewNode->next = after;
			return;
		}
		tmp = tmp->next;
	}
	if (*ppos == tmp)
	{
		tmp->next = NewNode;
		return;
	}
	perror("The pointer does not exist");
}

// 单链表删除pos位置之后的值
void SListEraseAfter(SListNode** pplist, SListNode** ppos)
{
	if ((*ppos == NULL) && (*pplist = NULL))
		return;
	else if ((*ppos)->next == NULL)
		return;

	SListNode* tmp = *pplist;
	SListNode* after = *pplist;
	SListNode* aafter = *pplist;

	while ((tmp->next) != NULL)
	{
		after = tmp->next;
		aafter = after->next;

		if (tmp == *ppos)
		{
			free(after);
			after = NULL;
			tmp->next = aafter;
			return;
		}
		tmp = tmp->next;
	}
	if (*ppos == tmp)
		return;
	else
		perror("The pointer does not exist");
}

// 在pos的前面插入
void SLTInsert(SListNode** pplist, SListNode** ppos, SLTDateType x)
{
	assert(pplist);

	if (*pplist == *ppos)
	{
		SListPushFront(pplist, x);
		return;
	}

	SListNode* NewNode = BuySListNode(x);

	SListNode* tmp = *pplist;
	SListNode* prev = *pplist;

	while (tmp->next)
	{
		if (tmp == *ppos)
		{
			prev->next = NewNode;
			NewNode->next = tmp;
			return;
		}
		prev = tmp;
		tmp = tmp->next;
	}
	perror("The pointer does not exist");
}

// 删除pos位置
void SLTErase(SListNode** pplist, SListNode** ppos)
{
	if ((*ppos == NULL) || (*pplist == NULL))
	{
		return;
	}
	else if ((*ppos)->next == NULL)
	{
		SListPopBack(pplist);
		return;
	}

	SListNode* tmp = *pplist;
	SListNode* befor = *pplist;
	SListNode* after = *pplist;

	while ((tmp->next) != NULL)
	{
		after = tmp->next;

		if (tmp == *ppos)
		{
			free(tmp);
			tmp = NULL;
			befor->next = after;
			return;
		}
		befor = tmp;
		tmp = tmp->next;
	}
	if (*ppos == tmp)
		return;
	else
		perror("The pointer does not exist");
}

你可能感兴趣的:(链表,数据结构)