链表
- 概念:链表是一种在物理结构上非连续、非顺序的存储结构;元素的逻辑逻辑顺序是通过链表中的指针连接次序;
- 链表的结构
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结点后面做插入
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;
}