文章目录
- 双向循环链表
- 定义
- 双向循环链表实现
- 结构体定义
- 静态函数列表
- 基础函数声明
- 静态函数实现
- 基础函数实现
- 创建双向循环链表 create_dlinkedlist
- 双向链表是否为空 empty_dlinkedlist
- 双向循环链表元素个数 size_dlinkedlist
- 清空双向循环链表 clear_dlinkedlist
- 销毁双向循环链表 destroy_dlinkedlist
- 在头部插入元素 push_front_dlinkedlist
- 在末尾插入元素 push_back_dlinkedlist
- 在指定位置插入元素 insert_dlinkedlist
- 在头部删除元素 pop_front_dlinkedlist
- 在末尾删除元素 pop_back_dlinkedlist
- 删除指定位置的元素 remove_dlinkedlist
- 根据值删除元素 delete_dlinkedlist
- 根据条件删除元素 delete_condition_dlinkedlist
- 修改pos位置的元素 update_dlinkedlist
- 修改第n个oldElem为newElem update_elem_dlinkedlistElemType newElem, size_t n);
- 修改第n个满足条件的元素为newElem update_condition_dlinkedlist
- 查找pos位置的元素 Type* elem_of_dlinkedlist
- 统计元素为elem的个数 count_dlinkedlist
- 统计满足条件元素的个数 count_condition_dlinkedlist
- 查找elem元素位置 find_dlinkedlist
- 查找满足条件的元素位置 find_condition_dlinkedlist
- 正向迭代 foreach_dlinkedlist
- 反向迭代 reverse_foreach_dlinkedlist
双向循环链表
定义
- 记录元素的同时要记录前一个结点和后一个结点的地址
- 再头尾插入删除结点 时间复杂度O(1)
ElemType elem;
struct DNode *prev;
struct DNode *next;
- 用柔性数组实现 任意类型元素双向循环链表
// struct DNode *node = (struct DNode*)malloc(DNODESIZE + elemSize);
// elemSize 是要存储元素类型的字节数
struct DNode *prev;
struct DNode *next;
char elem[0]; // 柔性数组
双向循环链表实现
结构体定义
#define SUCCESS 0
#define FAILURE -1
typedef int ElemType;
// 双向(循环)链表结点
struct DNode {
ElemType elem; // 元素
struct DNode *prev; // 指向上一个结点
struct DNode *next; // 指向下一个结点
};
#define DNODESIZE sizeof(struct DNode)
// 双向循环链表类型
typedef struct DNode* DLinkedList;
静态函数列表
// 创建双向(循环)链表的结点
static struct DNode *create_dnode(ElemType elem, struct DNode *prev, struct DNode *next);
// 再结点node后面插入结点
static int insert_after(struct DNode *node, ElemType elem);
// 再结点node前面插入结点
static int insert_before(struct DNode *node, ElemType elem);
// 删除node结点
static int delete_dnode(struct DNode *node, ElemType *pElem);
// 获取pos位置上结点
struct DNode *get_dnode(DLinkedList list, size_t pos);
基础函数声明
// 创建双向循环链表 创建一个头结点 且让头结点的prev和next指向头结点
// 头结点本身不存在数据
DLinkedList create_dlinkedlist(void);
// 双向链表是否为空
bool empty_dlinkedlist(DLinkedList list);
// 双向循环链表元素个数
size_t size_dlinkedlist(DLinkedList list);
// 清空双向循环链表
void clear_dlinkedlist(DLinkedList list);
// 销毁双向循环链表
void destroy_dlinkedlist(DLinkedList list);
// 在头部插入元素
int push_front_dlinkedlist(DLinkedList list, ElemType elem);
// 在末尾插入元素
int push_back_dlinkedlist(DLinkedList list, ElemType elem);
// 在指定位置插入元素
int insert_dlinkedlist(DLinkedList list, size_t pos, ElemType elem);
// 在头部删除元素
int pop_front_dlinkedlist(DLinkedList list, ElemType *pElem);
// 在末尾删除元素
int pop_back_dlinkedlist(DLinkedList list, ElemType *pElem);
// 删除指定位置的元素
int remove_dlinkedlist(DLinkedList list, size_t pos, ElemType *pElem);
// 根据值删除元素
int delete_dlinkedlist(DLinkedList list, ElemType elem, size_t n);
// 根据条件删除元素
int delete_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType), size_t n);
// 修改pos位置的元素
int update_dlinkedlist(DLinkedList list, size_t pos, ElemType newElem);
// 修改第n个oldElem为newElem
int update_elem_dlinkedlist(DLinkedList list, ElemType oldElem, ElemType newElem, size_t n);
// 修改第n个满足条件的元素为newElem
int update_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType), ElemType newElem, size_t n);
// 查找pos位置的元素
ElemType* elem_of_dlinkedlist(DLinkedList list, size_t pos);
// 统计元素为elem的个数
int count_dlinkedlist(DLinkedList list, ElemType elem);
// 统计满足条件元素的个数
int count_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType));
// 查找elem元素位置
int find_dlinkedlist(DLinkedList list, ElemType elem, size_t n);
// 查找满足条件的元素位置
int find_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType), size_t n);
// 正向迭代
void foreach_dlinkedlist(DLinkedList list, void (*foreach)(ElemType*));
// 反向迭代
void reverse_foreach_dlinkedlist(DLinkedList list, void (*foreach)(ElemType*));
静态函数实现
创建双向(循环)链表的结点 create_dnode
static struct DNode *create_dnode(ElemType elem, struct DNode *prev, struct DNode *next) {
struct DNode *node = (struct DNode*)malloc(DNODESIZE);
if (node != NULL) { // 申请成功 赋值
node->elem = elem;
node->prev = prev;
node->next = next;
}
return node;
}
再结点node后面插入结点 insert_after
// 在结点1后面插入元素
/*
node为结点1,node->next为结点3,要插入结点2(prev已经指向结点1,next已经指向结点3)
先将结点3的prev指向结点2
再将结点1的next指向结点2
*/
static int insert_after(struct DNode *node, ElemType elem) {
struct DNode *insNode = create_dnode(elem, node, node->next); // 结点2
if (insNode == NULL) {
return FAILURE;
}
node->next->prev = insNode; // 结点3的prev指向结点2
node->next = insNode; // 结点1的next指向结点2
return SUCCESS;
}
再结点node前面插入结点 insert_before
// 在结点1前面插入元素
/*
node为结点1,node->prev为结点3,要插入结点2(prev已经指向结点3,next已经指向结点1)
先将结点3的next指向结点2
再将结点1的prev指向结点2
*/
static int insert_before(struct DNode *node, ElemType elem) {
struct DNode *insNode = create_dnode(elem, node->prev, node); // 结点2
if (insNode == NULL) {
return FAILURE;
}
node->prev->next = insNode; // 结点3的next指向结点2
node->prev = insNode; // 将结点1的prev指向结点2
return SUCCESS;
}
删除node结点 delete_dnode
// 删除node结点
static int delete_dnode(struct DNode *node, ElemType *pElem) {
if (pElem != NULL) {
*pElem = node->elem; // 返回删除的元素
}
node->next->prev = node->prev;
node->prev->next = node->next;
free(node); // 释放删除的结点
return SUCCESS;
}
获取pos位置上结点 get_dnode
// 获取pos位置上结点
struct DNode *get_dnode(DLinkedList list, size_t pos) {
struct DNode *node = list->next;
size_t i;
for (i = 1; i < pos && node != list; ++i) {
node = node->next;
}
if (node == list && i < pos) {
return NULL;
}
return node;
}
基础函数实现
创建双向循环链表 create_dlinkedlist
// 创建一个头结点 且让头结点的prev和next指向头结点
// 头结点本身不存在数据
DLinkedList create_dlinkedlist(void) {
DLinkedList list = (DLinkedList)malloc(DNODESIZE);
if (list != NULL) {
list->prev = list->next = list; // 没有元素所以指针都指向自己
}
return list;
}
双向链表是否为空 empty_dlinkedlist
// 双向链表是否为空
bool empty_dlinkedlist(DLinkedList list) {
assert(list != NULL);
return list->prev == list && list->next == list; // 等于自己就为空
}
双向循环链表元素个数 size_dlinkedlist
size_t size_dlinkedlist(DLinkedList list) {
assert(list != NULL);
size_t size = 0;
struct DNode *node;
for (node = list->next; node != list; node = node->next) { // 循环到头结点结束
++size;
}
return size;
}
清空双向循环链表 clear_dlinkedlist
void clear_dlinkedlist(DLinkedList list) {
assert(list != NULL);
struct DNode *node, *next;
for (node = list->next; node != list; node = node->next) {
next = node->next; // 先记录下一个地址
free(node); // 每个结点都要释放,否在会导致内存泄漏
}
list->prev = list->next = list;
}
销毁双向循环链表 destroy_dlinkedlist
void destroy_dlinkedlist(DLinkedList list) {
assert(list != NULL);
clear_dlinkedlist(list);
free(list);
}
在头部插入元素 push_front_dlinkedlist
int push_front_dlinkedlist(DLinkedList list, ElemType elem) {
assert(list != NULL);
return insert_after(list, elem); // 调用静态函数
// return insert_before(list->next, elem);
}
在末尾插入元素 push_back_dlinkedlist
int push_back_dlinkedlist(DLinkedList list, ElemType elem) {
assert(list != NULL);
return insert_before(list, elem);
// return insert_after(list->prev, elem);
}
在指定位置插入元素 insert_dlinkedlist
int insert_dlinkedlist(DLinkedList list, size_t pos, ElemType elem) {
assert(list != NULL);
if (pos == 0) {
return FAILURE;
}
struct DNode *node = get_dnode(list, pos); // 先获取指定位置的元素 然后再其之前插入元素
if (node == NULL) {
return FAILURE;
}
return insert_before(node, elem);
}
在头部删除元素 pop_front_dlinkedlist
int pop_front_dlinkedlist(DLinkedList list, ElemType *pElem) {
assert(list != NULL);
if (list->next == list) {
return FAILURE;
}
return delete_dnode(list->next, pElem);
}
在末尾删除元素 pop_back_dlinkedlist
int pop_back_dlinkedlist(DLinkedList list, ElemType *pElem) {
assert(list != NULL);
if (list->prev == list) {
return FAILURE;
}
return delete_dnode(list->prev, pElem);
}
删除指定位置的元素 remove_dlinkedlist
int remove_dlinkedlist(DLinkedList list, size_t pos, ElemType *pElem) {
assert(list != NULL);
if (pos == 0) {
return FAILURE;
}
struct DNode *node = get_dnode(list, pos); // 先获取要删除元素的结点地址
if (node == NULL || node == list) {
return FAILURE;
}
return delete_dnode(node, pElem);
}
根据值删除元素 delete_dlinkedlist
n为0全部删除
int delete_dlinkedlist(DLinkedList list, ElemType elem, size_t n) {
assert(list != NULL);
struct DNode *node = list->next;
struct DNode *next = NULL;
int cnt = 0;
while (node != list) {
if (node->elem == elem) {
if (n == 0) {
next = node->next;
delete_dnode(node, NULL);
node = next;
++cnt;
} else {
if (--n == 0) {
delete_dnode(node, NULL);
return 1;
} else {
node = node->next; // n不为零 向后移
}
}
} else {
node = node->next; // 不等于elem 向后移
}
}
return cnt;
}
根据条件删除元素 delete_condition_dlinkedlist
自定义回调函数condition n为0全部删除
int delete_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType), size_t n) {
assert(list != NULL && condition != NULL);
struct DNode *node = list->next;
struct DNode *next = NULL;
int cnt = 0;
while (node != list) {
if (condition(node->elem)) {
if (n == 0) {
next = node->next;
delete_dnode(node, NULL);
node = next;
++cnt;
} else {
if (--n == 0) {
delete_dnode(node, NULL);
return 1;
} else {
node = node->next;
}
}
} else {
node = node->next;
}
}
return cnt;
}
修改pos位置的元素 update_dlinkedlist
int update_dlinkedlist(DLinkedList list, size_t pos, ElemType newElem) {
assert(list != NULL);
if (pos == 0) {
return FAILURE;
}
struct DNode *node = get_dnode(list, pos); // 获取要修改元素的地址
if (node == NULL || node == list) {
return FAILURE;
}
node->elem = newElem;
return SUCCESS;
}
修改第n个oldElem为newElem update_elem_dlinkedlistElemType newElem, size_t n);
n为0全部修改
int update_elem_dlinkedlist(DLinkedList list, ElemType oldElem, ElemType newElem, size_t n) {
assert(list != NULL);
int cnt = 0;
struct DNode *node = list->next;
for (; node != list; node = node->next) {
if (node->elem == oldElem) {
if (n == 0) {
node->elem = newElem;
++cnt;
} else {
if (--n == 0) {
node->elem = newElem;
return 1;
}
}
}
}
return cnt;
}
修改第n个满足条件的元素为newElem update_condition_dlinkedlist
自定义回调函数condition n为0全部修改
int update_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType), ElemType newElem, size_t n) {
assert(list != NULL && condition != NULL);
int cnt = 0;
struct DNode *node = list->next;
for (; node != list; node = node->next) {
if (condition(node->elem)) {
if (n == 0) {
node->elem = newElem;
++cnt;
} else {
if (--n == 0) {
node->elem = newElem;
return 1;
}
}
}
}
return cnt;
}
查找pos位置的元素 Type* elem_of_dlinkedlist
ElemType* elem_of_dlinkedlist(DLinkedList list, size_t pos) {
assert(list != NULL);
if (pos == 0) {
return NULL;
}
struct DNode *node = get_dnode(list, pos);
if (node == NULL || node == list) {
return NULL;
}
return &node->elem; // 返回地址
}
统计元素为elem的个数 count_dlinkedlist
int count_dlinkedlist(DLinkedList list, ElemType elem) {
assert(list != NULL);
int cnt = 0;
struct DNode *node = list->next;
for (; node != list; node = node->next) {
if (node->elem == elem) {
++cnt;
}
}
return cnt;
}
统计满足条件元素的个数 count_condition_dlinkedlist
自定义回调函数condition
int count_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType)) {
assert(list != NULL && condition != NULL);
int cnt = 0;
struct DNode *node = list->next;
for (; node != list; node = node->next) {
if (condition(node->elem)) {
++cnt;
}
}
return cnt;
}
查找elem元素位置 find_dlinkedlist
int find_dlinkedlist(DLinkedList list, ElemType elem, size_t n) {
assert(list != NULL);
if (n == 0) {
return 0;
}
struct DNode *node = list->next;
size_t pos = 0;
for (; node != list; node = node->next) {
++pos;
if (node->elem == elem) {
if (--n == 0) {
return pos;
}
}
}
return 0; // 0为没有找到
}
查找满足条件的元素位置 find_condition_dlinkedlist
自定义回调函数condition
int find_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType), size_t n) {
assert(list != NULL && condition != NULL);
if (n == 0) {
return 0;
}
struct DNode *node = list->next;
size_t pos = 0;
for (; node != list; node = node->next) {
++pos;
if (condition(node->elem)) {
if (--n == 0) {
return pos;
}
}
}
return 0;
}
正向迭代 foreach_dlinkedlist
可以实现打印等功能
void foreach_dlinkedlist(DLinkedList list, void (*foreach)(ElemType*)) {
assert(list != NULL && foreach != NULL);
struct DNode *node;
for (node = list->next; node != list; node = node->next) {
foreach(&node->elem);
}
}
反向迭代 reverse_foreach_dlinkedlist
void reverse_foreach_dlinkedlist(DLinkedList list, void (*foreach)(ElemType*)) {
assert(list != NULL && foreach != NULL);
struct DNode *node;
for (node = list->prev; node != list; node = node->prev) {
foreach(&node->elem);
}
}
5807

被折叠的 条评论
为什么被折叠?



