04-链表-哨兵节点/头节点/头指针

单链表+哨兵节点

1.概况

在学习链表时,一定要区分清楚有关哨兵节点,头节点,头指针基本概念

哨兵节点(Sentinel Node)、头节点(Head Node)和头指针(Head Pointer)是常用的概念,它们在数据结构中有不同的作用和含义。

----哨兵节点

哨兵节点(Sentinel Node):哨兵节点是一种特殊节点,它在链表或树等数据结构中用于简化边界情况的处理。通常哨兵节点的值或内容是无效的,它并不存储有效数据。哨兵节点可以帮助简化一些操作,如在链表中插入节点时不需要特别处理空链表和非空链表的情况。

---- 头节点

链表第一个真实节点或头节点(Head Node):头节点是链表中的第一个节点,也可以称为首节点。它存储了链表的一些附加信息,如链表的长度或其他属性。头节点可以是有效节点,即存储了真正的数据,也可以是哨兵节点。

----头指针

头指针(Head Pointer):头指针是指向链表(或其他数据结构)的第一个节点的指针。它是一个指针变量,通常存储节点的地址,用于访问和操作整个链表。头指针可以指向头节点或者直接指向第一个有效节点。

综上所述,哨兵节点是一种特殊节点,用于简化边界处理。头节点是链表中的第一个节点,可以携带附加信息。头指针是指向链表的第一个节点的指针。它们在数据结构中各有不同的作用。

2.基于哨兵节点的链表操作

C代码实现

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

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20
/**
带哨兵节点的单链表结构
*/
typedef int Status;
typedef int ElemType;

/*创建节点元素*/
typedef struct Node {
	ElemType data;
	struct Node *next;
} Node;

/*方法声明*/
Node* initList();
void addFirst(Node *head, ElemType value);
void addLast(Node *head, ElemType value);
void insert(Node *head, int index, ElemType value);
Node* getNode(Node *head, int index);
void remove(Node *head, int index);
void loop(Node *head);

int main() {
	Node *head = initList();
	addLast(head,1);	//0
	addLast(head,2);	//1
	addLast(head,3);	//2
	addLast(head,4);	//3
	insert(head, 4, 10);
	remove(head, 0);
	loop(head->next);
	return 0;
}
/**
初始化链表
*/
Node* initList() {
	//创建哨兵节点
	Node *head = (Node*) malloc(sizeof(Node));
	head->next = NULL;
	return head;
}

/**
插入链表元素
*/
//头插法
void addFirst(Node *head, ElemType value) {
	Node *p = head;
	//创建新节点
	Node *s = (Node*) malloc(sizeof(Node));
	s->data = value;
	s->next = p->next;
	p->next = s;
}

//尾插法
void addLast(Node *head, ElemType value) {
	// 遍历找到最后一个节点
	Node* p = head;
	while (p->next != NULL) {
		p = p->next;
	}
	// 创建新节点
	Node* s = (Node*)malloc(sizeof(Node));
	s->data = value;
	s->next = NULL;
	// 将新节点连接到最后一个节点的 next 指针上
	p->next = s;
}

//任意位置插入
void insert(Node *head, int index, ElemType value){
	//获取索引前一个位置的节点
	Node *pres = getNode(head,index-1); 
	Node *newNode = (Node*) malloc(sizeof(Node));
	newNode->data = value;
	newNode->next = pres->next;
	//插入节点
	pres->next = newNode; 	
}


/**
查找索引元素 
*/
Node* getNode(Node *head, int index){
	int i = -1;	//因为存在哨兵节点,所以i要从-1计数 
	for(Node *p = head; p != NULL; p = p->next){
		if(i == index){ return p;}
		i++;
	}
	return NULL;
}


/**
遍历链表元素
*/
void loop(Node *head) {
	for(Node *p = head; p != NULL; p = p->next) {
		printf("%d\n",p->data);
	}
}

/**
删除元素 
*/
void remove(Node *head, int index){
	Node *pres = getNode(head, index-1);
	Node *remove = pres->next;
	pres->next = remove->next;
} 
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值