之前学习了单链表的相关操作,但是单链表有一个缺点,无法快速访问前驱结点,当查找到某个元素时,如果想要找到前面元素的结点,需要再次从头遍历,这样就比较麻烦,那么是否可以在节点中再增加一个指针指向前驱结点,答案是可以的。增加了指向前驱结点的指针的链表称为双链表
链表分类
链表还有一种常用,那就是循环链表,顾名思义,这种链表就是头尾相连
- 单链表
- 双链表
- 双向循环链
//DList.h
//双向
//循环
//有头
#pragma once
//定义结点
typedef struct DListNode {
int data;
struct DListNode* pre; //指向前驱结点的指针
struct DListNode* next; //指向后继结点的指针
}DListNode;
void DListInit(DListNode** ppHead); //链表初始化
void DListClear(DListNode* pHead); //清空链表(保留头结点)
void DListDestroy(DListNode* pHead); //清空链表(不保留头结点)
void DListInsert(DListNode* pHead, DListNode* pos, int data); //再结点pos的位置插入元素data
void DListPushFront(DListNode* pHead, int data); //头插
void DListPushBack(DListNode* pHead,int data); //尾插
void DListEarse(DListNode* pHead, DListNode* pos); //删除结点pos
void DListPopFront(DListNode* pHead); //头删
void DListPopBack(DListNode* pHead); //尾删
//DList.c
#include "DList.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
void DListInit(DListNode** ppHead) {
assert(ppHead != NULL);
DListNode* pHead = (DListNode*)malloc(sizeof(DListNode));
pHead->next = pHead;
pHead->pre = pHead;
*ppHead = pHead;
}
// 清空,保留根节点
void DListClear(DListNode* pHead) {
DListNode* cur = pHead->next;
DListNode* next;
while (cur != pHead) {
next = cur->next;
free(cur);
cur = next;
}
}
//清空,不保留根节点
void DListDestroy(DListNode* pHead) {
DListClear(pHead);
free(pHead);
pHead->next = NULL;
}
void DListInsert(DListNode* pHead, DListNode* pos, int data) {
assert(pHead!= NULL);
DListNode* newNode = (DListNode*)malloc(sizeof(DListNode));
newNode ->data = data;
newNode->pre = pos->pre;
newNode->next = pos;
pos->pre->next = newNode;
pos->pre = newNode;
}
void DListPushFront(DListNode* pHead,int data) {
DListInsert(pHead, pHead->next, data);
}
void DListPushBack(DListNode* pHead, int data) {
DListInsert(pHead, pHead, data);
}
void DListEarse(DListNode* pHead, DListNode* pos) {
//删除的肯定不能是头
pos->pre->next = pos->next;
pos->next->pre = pos->pre;
free(pos);
}
void DListPopFront(DListNode* pHead) {
DListEarse(pHead, pHead->next);
}
void DListPopBack(DListNode* pHead) {
DListEarse(pHead, pHead->pre);
}