单链表:
概念:
通过一组任意的存储单元来存储元素,不需要地址上连续
特点:
1,不需要连续的存储空间
2,每次查找元素都需要从头遍历链表
3,链表节点除了自身元素外,还要有指向下一个节点的指针
节点描述:
typedef struct DNode {
int val;
DNode* next;
}DNode;
单链表描述:
typedef struct DList {
DNode* head;
}DList,*PDlist;
创建节点:
DNode* CreatDNode(DNode* node, int val) {
DNode* p = (DNode*)malloc(sizeof(DNode));//动态申请内存
p->val = val;
p->next = NULL;
}
链表初始化:
void InitDList(PDlist plist) {
plist->head = NULL;
}
头插法:
void InsertHead(PDlist plist,int val) {
assert(plist != NULL);
DNode* p = CreatDNode(val);
if (plist->head == NULL) {
plist->head = p;
}
else {
p->next = plist->head;
plist->head = p;
}
}
尾插法:
void InsertTail(PDlist plist, int val) {
assert(plist != NULL);
DNode* p = CreatDNode(val);
if (plist->head == NULL) {
plist->head = p;
}
else {
DNode* curr = plist->head;
while (curr->next != NULL) {
curr = curr->next;
}
curr->next = p;
}
}
头删:
void DeleteHead(PDlist plist) {
assert(plist->head != NULL);
if (plist->head->next == NULL) {
return;
}
else {
DNode* p = plist->head;
plist->head = p->next;
free(p);
}
}
尾删:
void DeleteTail(PDlist plist) {
assert(plist->head != NULL);
if (plist->head->next == NULL) {
return;
}
else {
DNode* curr = plist->head;
while (curr->next->next != NULL) {
curr = curr->next;
}
free(curr->next);
curr->next = NULL;
}
}
删除节点:
void DeleteVal(PDlist plist, int val) {
assert(plist->head != NULL);
// 处理头节点是要删除的节点的情况
while (plist->head != NULL && plist->head->val == val) {
DNode* temp = plist->head;
plist->head = plist->head->next;
free(temp);
}
DNode* pre = plist->head;
DNode* curr = pre->next;
while (curr != NULL) {
if (curr->val == val) {
pre->next = curr->next;
free(curr);
curr = pre->next; // 更新 curr 指针位置
}
else {
pre = curr;
curr = curr->next;
}
}
}
输出链表:
void show(PDlist plist) {
assert(plist != NULL);
DNode* curr = plist->head;
while (curr != NULL) {
printf("%d ",curr->val);
curr = curr->next;
}
}