线性表之带表头结点的单链表存储结构

一、什么是带表头的单链表

单链表中,因为头结点没有直接前驱结点,所以在进行插入和删除操作时,需要特殊的处理。为了简化操作,在单链表之前添加一个空的头结点,实际的元素结点从第二个结点开始,由此称为带表头的单链表

二、各个功能实现

(一)初始化

带表头单链表的初始化是指:构造一个仅带有一个表头结点的空单链表。

1、算法步骤

(1)为表头结点申请动态空间
(2)设置头结点的直接后继结点,即第一个数据结点为 N U L L NULL NULL,即构造了一个空链表
(3)链表长度置 0 0 0

2、算法代码
// 带表头单链表的初始化
Status Init(HeaderSingleList* list)
{
	list->head = malloc(sizeof(Node));
	if (!list->head)
	{
		return Error;
	}
	list->head->link = NULL;
	list->n = 0;
	return OK;
}

(二)插入

带表头单链表的每个节点都有直接前驱结点,所以在进行插入操作时无需特殊化处理,简化了插入操作。

1、算法步骤

(1)判断所要插入的位置是否越界
(2)为新节点 n e w N o d e newNode newNode 申请动态空间,并给结点数据段赋值
(3)找到要插入位置的前一个结点 b e f o r e N o d e beforeNode beforeNode
(4)将 n e w N o d e newNode newNode 的后继结点赋值为 b e f o r e N o d e − > l i n k beforeNode->link beforeNode>link b e f o r e N o d e beforeNode beforeNode 结点的后继结点赋值为 n e w N o d e newNode newNode
(5)表长++

2、算法代码
// 带表头单链表的插入
Status Insert(HeaderSingleList* list, int i, int value)
{
	// 如果插入的位置越界,则返回错误
	if (i < -1 || i > list->n - 1)
	{
		return Error;
	}
	Node* newNode = malloc(sizeof(Node));
	Node* before = list->head;
	for (int j = 0; j <= i; j++)
	{
		before = before->link;
	}
	
	newNode->value = value;
	newNode->link = before->link;
	before->link = newNode;
	
	list->n++;
}

(三)删除

带表头单链表的每个节点都有直接前驱结点,所以在进行删除操作时无需特殊化处理,简化了删除操作。

1、算法步骤

(1)替换link
(2)释放删除的空间

2、算法代码
void Delete(HeaderSingleList* list, int i)
{
	if (list->n == 0)
	{
		return Error;
	}
	if (i < 0 || i >list->n - 1)
	{
		return Error;
	}
	Node* beforeNode = list->head;
	Node* deleteNode = NULL;
	// 找到要删除节点的前一个结点
	for (int j = 0; j < i; j++)
	{
		beforeNode = beforeNode->link;
	}
	// 此时的 beforNode 是所要删除结点的前一个结点
	deleteNode = beforeNode->link;					// 要删除的结点deleteNode 为 beforNode 的下一个结点
	beforeNode->link = deleteNode->link;			// 将要删除结点的前一个结点的 link 指向 要删除结点的下一个结点
	free(deleteNode);
	printf("调用了 Delete(\%d) 函数\n", i);
	list->n--;
}

三、全部代码

#include <stdio.h>
#define ElemType int
#define Error 0
#define OK 1
#define Overflow 2
#define Underflow 3
#define NotPresent 4
#define Duplicate 5
typedef int Status;

// 结点结构体
typedef struct node
{
	ElemType value;
	struct node* link;

}Node;

// 单链表结构体
typedef struct headerSingleList
{
	Node* head;
	int n;
}HeaderSingleList;


// 带表头单链表的初始化
Status Init(HeaderSingleList* list)
{
	list->head = malloc(sizeof(Node));
	if (!list->head)
	{
		return Error;
	}
	list->head->link = NULL;
	list->n = 0;
	return OK;
}

// 带表头单链表的插入
Status Insert(HeaderSingleList* list, int i, int value)
{
	// 如果插入的位置越界,则返回错误
	if (i < -1 || i > list->n - 1)
	{
		return Error;
	}
	Node* newNode = malloc(sizeof(Node));
	Node* before = list->head;
	for (int j = 0; j <= i; j++)
	{
		before = before->link;
	}
	
	newNode->value = value;
	newNode->link = before->link;
	before->link = newNode;
	
	list->n++;
}

void Delete(HeaderSingleList* list, int i)
{
	if (list->n == 0)
	{
		return Error;
	}
	if (i < 0 || i >list->n - 1)
	{
		return Error;
	}
	Node* beforeNode = list->head;
	Node* deleteNode = NULL;
	// 找到要删除节点的前一个结点
	for (int j = 0; j < i; j++)
	{
		beforeNode = beforeNode->link;
	}
	// 此时的 beforNode 是所要删除结点的前一个结点
	deleteNode = beforeNode->link;					// 要删除的结点deleteNode 为 beforNode 的下一个结点
	beforeNode->link = deleteNode->link;			// 将要删除结点的前一个结点的 link 指向 要删除结点的下一个结点
	free(deleteNode);
	printf("调用了 Delete(\%d) 函数\n", i);
	list->n--;
}

void GetValue(HeaderSingleList* list, int i, int* value)
{
	printf("调用了 GetValue() 函数\n");
	Node* node = list->head;
	for (int j = 0; j < i; j++)
	{
		node = node->link;
	}
	*value = node->value;
}

// 单链表的销毁
void Destory(HeaderSingleList* list)
{
	printf("调用了 Destory() 函数\n");
	Node* node = list->head;
	while (list->head)
	{
		node = node->link;
		free(list->head);
		list->head = node;
	}
}

void PrintAllValue(HeaderSingleList* list)
{
	if (list->n == 0) {
		return Error;
	}
	Node* node = list->head->link;
	while (node)
	{
		printf("%d -> ", node->value);
		node = node->link;
	}
	printf("NULL\n\n");

}


int main()
{
	HeaderSingleList* list = malloc(sizeof(HeaderSingleList));
	Init(list);
	Insert(list, -1, 4);
	Insert(list, -1, 3);
	Insert(list, -1, 2);
	Insert(list, -1, 1);
	Insert(list, -1, 0);

	PrintAllValue(list);
	Delete(list, 1);
	PrintAllValue(list);
	Destory(list);
	PrintAllValue(list);

}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亦是远方

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值