链表中的插入、删除、查找

链表

  • 概念:链表是一种在物理结构上非连续、非顺序的存储结构;元素的逻辑逻辑顺序是通过链表中的指针连接次序;
  • 链表的结构
    1.双向和单向
    2.循环和非循环
    3.带头结点和不带头结点

链表的构造、初始化与销毁

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

typedef int SListDateType;

//链表的构造
//定义的不是链表的结构体,而是链表中一个节点的结构体
typedef struct ListNode {
	SListDateType value;  //链表中保存的值
	struct ListNode* next; //保存下一个节点的地址
} Node;

typedef struct SList {
	Node *first;
} SList;

//链表的初始化
void SListInit(SList *s) {
	assert(s != NULL);
	s->first = NULL;
}

//链表的销毁
void SListDestory(SList* s) {
	Node* next;
	for (Node* cur = s->first; cur != NULL; cur = next) {
		next = cur->next;
		free(cur);
	}
	s->first = NULL;
}

插入

头插
  • 头插就是在链表的头部插入一个新的结点
  • 实现代码
//头插
void SListPushFront(SList *s, SListDateType v) {
	Node *node = (Node*)malloc(sizeof(Node));
	node->value = v;
	node->next = s->first;
	s->first = node;
}
尾插
  • 尾插就是在链表的末尾插入一个新的节点
  • 实现代码
//尾插
void SListPushBack(SList *s, SListDateType v) {
	Node *node = (Node*)malloc(sizeof(Node));
	node->value = v;
	node->next = NULL;
	
	//链表为空的情况
	if (s->first == NULL) {
		s->first = node;
		return;
	}

	//链表至少有一个节点的情况
	Node* cur = s->first;
	while (cur->next != NULL) {      // 遍历链表
		cur = cur->next;
	}
	//cur->next一定是NULL
	cur->next = node;
}
在给定的pos结点处做插入
  • 在链表的某个pos结点处插入一个新的结点
  • 实现代码
// 在给定的pos结点后面做插入
void SListInsertAfter(SList* s, Node* pos, SListDateType v) {
	Node* node = (Node*)malloc(sizeof(Node));
	node->value = v;
	node->next = pos->next;
	pos->next = node;
}

删除

头删
  • 头删就是删除链表的头结点
  • 实现代码
//头删
void SListPopFront(SList *s) {
	assert(s != NULL);          //不能没有链表
	assert(s->first != NULL);   //不能没有节点

	Node* next = s->first->next;
	free(s->first);
	s->first = next;
	
}
尾删
  • 链表的尾删就是删除链表最后一个结点
  • 实现代码
//尾删
void SListPopBack(SList* s) {
	assert(s != NULL);          //不能没有链表
	assert(s->first != NULL);   //不能没有节点

	//链表中就一个节点
	if (s->first->next == NULL) {
		free(s->first);
		s->first = NULL;
		return;
	}
	else {
		Node* cur = s->first;
		while (cur->next->next != NULL) {
			cur = cur->next;
		}
		//cur是倒数第二个节点
	   //cur->next->next=NULL;
		free(cur->next);
		cur->next = NULL;
	}
}
删除给定的pos结点下一个结点
  • 给定了链表中的某个结点,删除这个节点的下一个节点
  • 前提保证:这个节点不是链表的最后一个节点
  • 实现代码
oid SListEraseAfter(SList* s, Node* pos) {
	Node* next = pos->next;
	pos->next = pos->next->next;
	free(next);
}
已知某个结点的值,找的这个结点,并删除
  • 已知在链表中的某个值v,删除这个这个值(也就是删除这个值所在的结点)
  • 实现代码
void SListRemove(SList* s, SListDateType v) {
	if (s->first == NULL) {
		//链表为NULL
		return;
	}
	if (s->first->value == v) {
		//v就是第一个节点的情况
		Node* next = s->first->next;
		free(s->first);
		s->first = next;
		return;
	}

	Node* cur = s->first;
	//v不是第一个结点,遍历链表找的这个数
	while(cur->next != NULL) {
		if (cur->next->value == v) {
			Node* next = cur->next->next;
			free(cur->next);
			cur->next = next;
			return;
		}
		cur = cur->next;
	}
}

查找

在链表中查找某个结点
  • 实现代码
//查找
Node* SListFind(SList* s, SListDateType v) {
	for (Node* cur = s->first; cur != NULL; cur = cur->next) {
		if (cur->value == v) {
			return cur;
		}
	}
	return NULL;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值