链表的声明
double_linked_list.h
#ifndef ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
#define ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H// 双向链表的节点
typedef struct doubleLinkedListNode {int data;struct doubleLinkedListNode *next; // 下一个节点struct doubleLinkedListNode *prev; // 上一个节点
} DoubleLinkedListNode;// 双向链表
typedef struct doubleLinkedList {DoubleLinkedListNode *head; // 头节点DoubleLinkedListNode *tail; // 尾节点
} DoubleLinkedList;#endif //ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
创建双向链表
double_linked_list.h
#ifndef ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
#define ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H// 双向链表的节点
typedef struct doubleLinkedListNode {int data;struct doubleLinkedListNode *next; // 下一个节点struct doubleLinkedListNode *prev; // 上一个节点
} DoubleLinkedListNode;// 双向链表
typedef struct doubleLinkedList {DoubleLinkedListNode head; // 头节点DoubleLinkedListNode tail; // 尾节点
} DoubleLinkedList;#endif //ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
double_linked_list.c
#include "double_linked_list.h"// 创建头节点
DoubleLinkedListNode *_newDoubleLinkedListNode(int value) {// 申请节点的空间DoubleLinkedListNode *node = malloc(sizeof(DoubleLinkedListNode));// 初始化node->next = NULL;node->prev = NULL;node->data = value;// 返回return node;
}// 创建双向链表
DoubleLinkedList *newDoubleLinkedList() {// 申请链表的内存DoubleLinkedList *list = malloc(sizeof(DoubleLinkedList));// 头节点DoubleLinkedListNode *head = _newDoubleLinkedListNode(0);// 尾结点DoubleLinkedListNode *tail = _newDoubleLinkedListNode(0);// 初始化list->head = head;list->tail = tail;// 返回return list;
}
释放双向链表内存
核心代码:
void freeDoubleLinkedList(DoubleLinkedList *list) {// 释放节点内存DoubleLinkedListNode *node = list->head->next;while (node->next != list->tail) {DoubleLinkedListNode *next = node->next;free(node);node = next;}// 释放首尾节点的内存free(list->head);free(list->tail);// 释放链表内存free(list);
}
double_linked_list.h
#ifndef ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
#define ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H// 公共头文件
#include "stdio.h"
#include "string.h"
#include "stdlib.h"// 双向链表的节点
typedef struct doubleLinkedListNode {int data;struct doubleLinkedListNode *next; // 下一个节点struct doubleLinkedListNode *prev; // 上一个节点
} DoubleLinkedListNode;// 双向链表
typedef struct doubleLinkedList {DoubleLinkedListNode *head; // 头节点DoubleLinkedListNode *tail; // 尾节点
} DoubleLinkedList;extern DoubleLinkedList *newDoubleLinkedList(); // 创建双向链表
extern void freeDoubleLinkedList(DoubleLinkedList *list); // 释放双向链表内存#endif //ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
double_linked_list.c
#include "double_linked_list.h"// 创建头节点
DoubleLinkedListNode *_newDoubleLinkedListNode(int value) {// 申请节点的空间DoubleLinkedListNode *node = malloc(sizeof(DoubleLinkedListNode));// 初始化node->next = NULL;node->prev = NULL;node->data = value;// 返回return node;
}// 创建双向链表
DoubleLinkedList *newDoubleLinkedList() {// 申请链表的内存DoubleLinkedList *list = malloc(sizeof(DoubleLinkedList));// 头节点DoubleLinkedListNode *head = _newDoubleLinkedListNode(0);// 尾结点DoubleLinkedListNode *tail = _newDoubleLinkedListNode(0);// 初始化list->head = head;list->tail = tail;// 返回return list;
}// 释放双向链表内存
void freeDoubleLinkedList(DoubleLinkedList *list) {// 释放节点内存DoubleLinkedListNode *node = list->head->next;while (node->next != list->tail) {DoubleLinkedListNode *next = node->next;free(node);node = next;}// 释放首尾节点的内存free(list->head);free(list->tail);// 释放链表内存free(list);
}
判断链表是否为空
核心代码:
int isEmptyDoubleLinkedList(DoubleLinkedList *list) {return list != NULL && list->head->next == list->tail;
}
优化创建链表的代码,让头节点下一个节点指向尾节点,尾节点的上一个节点指向头节点。
DoubleLinkedList *newDoubleLinkedList() {// 申请链表的内存DoubleLinkedList *list = malloc(sizeof(DoubleLinkedList));// 头节点DoubleLinkedListNode *head = newDoubleLinkedListNode(0);// 尾结点DoubleLinkedListNode *tail = newDoubleLinkedListNode(0);// 初始化list->head = head;list->tail = tail;// 关系list->head->next = list->tail;list->tail->prev = list->head;// 返回return list;
}
double_linked_list.h
#ifndef ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
#define ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H// 公共头文件
#include "stdio.h"
#include "string.h"
#include "stdlib.h"// 双向链表的节点
typedef struct doubleLinkedListNode {int data;struct doubleLinkedListNode *next; // 下一个节点struct doubleLinkedListNode *prev; // 上一个节点
} DoubleLinkedListNode;// 双向链表
typedef struct doubleLinkedList {DoubleLinkedListNode *head; // 头节点DoubleLinkedListNode *tail; // 尾节点
} DoubleLinkedList;extern DoubleLinkedList *newDoubleLinkedList(); // 创建双向链表
extern void freeDoubleLinkedList(DoubleLinkedList *list); // 释放双向链表内存
extern int isEmptyDoubleLinkedList(DoubleLinkedList *list); // 判断是否为空链表#endif //ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
double_linked_list.c
#include "double_linked_list.h"// 创建头节点
DoubleLinkedListNode *newDoubleLinkedListNode(int value) {// 申请节点的空间DoubleLinkedListNode *node = malloc(sizeof(DoubleLinkedListNode));// 初始化node->next = NULL;node->prev = NULL;node->data = value;// 返回return node;
}// 创建双向链表
DoubleLinkedList *newDoubleLinkedList() {// 申请链表的内存DoubleLinkedList *list = malloc(sizeof(DoubleLinkedList));// 头节点DoubleLinkedListNode *head = newDoubleLinkedListNode(0);// 尾结点DoubleLinkedListNode *tail = newDoubleLinkedListNode(0);// 初始化list->head = head;list->tail = tail;// 关系list->head->next = list->tail;list->tail->prev = list->head;// 返回return list;
}// 释放双向链表内存
void freeDoubleLinkedList(DoubleLinkedList *list) {// 释放节点内存DoubleLinkedListNode *node = list->head->next;while (node->next != list->tail) {DoubleLinkedListNode *next = node->next;free(node);node = next;}// 释放首尾节点的内存free(list->head);free(list->tail);// 释放链表内存free(list);
}// 判断是否为空链表
int isEmptyDoubleLinkedList(DoubleLinkedList *list) {return list != NULL && list->head->next == list->tail;
}
获取链表的元素个数
给双向链表的结构加上size这个属性,每个新增的时候,这个数都+1,每次删除的时候都-1,这样这个属性的值代表的就是链表中元素的个数。
核心代码:
int sizeDoubleLinkedList(DoubleLinkedList *list) {return list->size;
}
double_linked_list.h
#ifndef ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
#define ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H// 公共头文件
#include "stdio.h"
#include "string.h"
#include "stdlib.h"// 双向链表的节点
typedef struct doubleLinkedListNode {int data;struct doubleLinkedListNode *next; // 下一个节点struct doubleLinkedListNode *prev; // 上一个节点
} DoubleLinkedListNode;// 双向链表
typedef struct doubleLinkedList {DoubleLinkedListNode *head; // 头节点DoubleLinkedListNode *tail; // 尾节点int size; // 节点的个数
} DoubleLinkedList;extern DoubleLinkedList *newDoubleLinkedList(); // 创建双向链表
extern void freeDoubleLinkedList(DoubleLinkedList *list); // 释放双向链表内存
extern int isEmptyDoubleLinkedList(DoubleLinkedList *list); // 判断是否为空链表
extern int sizeDoubleLinkedList(DoubleLinkedList *list); // 获取链表的元素个数#endif //ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
double_linked_list.c
#include "double_linked_list.h"// 创建头节点
DoubleLinkedListNode *newDoubleLinkedListNode(int value) {// 申请节点的空间DoubleLinkedListNode *node = malloc(sizeof(DoubleLinkedListNode));// 初始化node->next = NULL;node->prev = NULL;node->data = value;// 返回return node;
}// 创建双向链表
DoubleLinkedList *newDoubleLinkedList() {// 申请链表的内存DoubleLinkedList *list = malloc(sizeof(DoubleLinkedList));// 头节点DoubleLinkedListNode *head = newDoubleLinkedListNode(0);// 尾结点DoubleLinkedListNode *tail = newDoubleLinkedListNode(0);// 初始化list->head = head;list->tail = tail;list->size = 0;// 关系list->head->next = list->tail;list->tail->prev = list->head;// 返回return list;
}// 释放双向链表内存
void freeDoubleLinkedList(DoubleLinkedList *list) {// 释放节点内存DoubleLinkedListNode *node = list->head->next;while (node->next != list->tail) {DoubleLinkedListNode *next = node->next;free(node);node = next;}// 释放首尾节点的内存free(list->head);free(list->tail);// 释放链表内存free(list);
}// 判断是否为空链表
int isEmptyDoubleLinkedList(DoubleLinkedList *list) {return list != NULL && list->head->next == list->tail;
}// 获取链表的元素个数
int sizeDoubleLinkedList(DoubleLinkedList *list) {return list->size;
}
打印链表的内容
核心代码:
void printDoubleLinkedList(DoubleLinkedList *list) {if (list == NULL) {return;}if (list->head == NULL || list->head->next == NULL) {return;}DoubleLinkedListNode *current = list->head->next;while (current != list->tail) {printf("%d ", current->data);current = current->next;}printf("\n");
}
double_linked_list.h
#ifndef ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
#define ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H// 公共头文件
#include "stdio.h"
#include "string.h"
#include "stdlib.h"// 双向链表的节点
typedef struct doubleLinkedListNode {int data;struct doubleLinkedListNode *next; // 下一个节点struct doubleLinkedListNode *prev; // 上一个节点
} DoubleLinkedListNode;// 双向链表
typedef struct doubleLinkedList {DoubleLinkedListNode *head; // 头节点DoubleLinkedListNode *tail; // 尾节点int size; // 节点的个数
} DoubleLinkedList;extern DoubleLinkedList *newDoubleLinkedList(); // 创建双向链表
extern void freeDoubleLinkedList(DoubleLinkedList *list); // 释放双向链表内存
extern int isEmptyDoubleLinkedList(DoubleLinkedList *list); // 判断是否为空链表
extern int sizeDoubleLinkedList(DoubleLinkedList *list); // 获取链表的元素个数
extern void printDoubleLinkedList(DoubleLinkedList *list); // 打印链表的内容#endif //ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
double_linked_list.c
#include "double_linked_list.h"// 创建头节点
DoubleLinkedListNode *newDoubleLinkedListNode(int value) {// 申请节点的空间DoubleLinkedListNode *node = malloc(sizeof(DoubleLinkedListNode));// 初始化node->next = NULL;node->prev = NULL;node->data = value;// 返回return node;
}// 创建双向链表
DoubleLinkedList *newDoubleLinkedList() {// 申请链表的内存DoubleLinkedList *list = malloc(sizeof(DoubleLinkedList));// 头节点DoubleLinkedListNode *head = newDoubleLinkedListNode(0);// 尾结点DoubleLinkedListNode *tail = newDoubleLinkedListNode(0);// 初始化list->head = head;list->tail = tail;list->size = 0;// 关系list->head->next = list->tail;list->tail->prev = list->head;// 返回return list;
}// 释放双向链表内存
void freeDoubleLinkedList(DoubleLinkedList *list) {// 释放节点内存DoubleLinkedListNode *node = list->head->next;while (node->next != list->tail) {DoubleLinkedListNode *next = node->next;free(node);node = next;}// 释放首尾节点的内存free(list->head);free(list->tail);// 释放链表内存free(list);
}// 判断是否为空链表
int isEmptyDoubleLinkedList(DoubleLinkedList *list) {return list != NULL && list->head->next == list->tail;
}// 获取链表的元素个数
int sizeDoubleLinkedList(DoubleLinkedList *list) {return list->size;
}// 打印链表的内容
void printDoubleLinkedList(DoubleLinkedList *list) {if (list == NULL) {return;}if (list->head == NULL || list->head->next == NULL) {return;}DoubleLinkedListNode *current = list->head->next;while (current != list->tail) {printf("%d ", current->data);current = current->next;}printf("\n");
}
添加元素到链表末尾
核心代码:
void appendDoubleLinkedList(DoubleLinkedList *list, int value) {if (list == NULL || list->head == NULL || list->tail == NULL) {return;}// 构造新节点DoubleLinkedListNode *node = newDoubleLinkedListNode(value);// 插入到末尾DoubleLinkedListNode *oldPrev = list->tail->prev;oldPrev->next = node;node->prev = oldPrev;node->next = list->tail;list->tail->prev = node;// 元素个数增加list->size++;
}
double_linked_list.h
#ifndef ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
#define ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H// 公共头文件
#include "stdio.h"
#include "string.h"
#include "stdlib.h"// 双向链表的节点
typedef struct doubleLinkedListNode {int data;struct doubleLinkedListNode *next; // 下一个节点struct doubleLinkedListNode *prev; // 上一个节点
} DoubleLinkedListNode;// 双向链表
typedef struct doubleLinkedList {DoubleLinkedListNode *head; // 头节点DoubleLinkedListNode *tail; // 尾节点int size; // 节点的个数
} DoubleLinkedList;extern DoubleLinkedList *newDoubleLinkedList(); // 创建双向链表
extern void freeDoubleLinkedList(DoubleLinkedList *list); // 释放双向链表内存
extern int isEmptyDoubleLinkedList(DoubleLinkedList *list); // 判断是否为空链表
extern int sizeDoubleLinkedList(DoubleLinkedList *list); // 获取链表的元素个数
extern void printDoubleLinkedList(DoubleLinkedList *list); // 打印链表的内容
extern void appendDoubleLinkedList(DoubleLinkedList *list, int value); // 将元素添加到链表末尾#endif //ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
double_linked_list.c
#include "double_linked_list.h"// 创建头节点
DoubleLinkedListNode *newDoubleLinkedListNode(int value) {// 申请节点的空间DoubleLinkedListNode *node = malloc(sizeof(DoubleLinkedListNode));// 初始化node->next = NULL;node->prev = NULL;node->data = value;// 返回return node;
}// 创建双向链表
DoubleLinkedList *newDoubleLinkedList() {// 申请链表的内存DoubleLinkedList *list = malloc(sizeof(DoubleLinkedList));// 头节点DoubleLinkedListNode *head = newDoubleLinkedListNode(0);// 尾结点DoubleLinkedListNode *tail = newDoubleLinkedListNode(0);// 初始化list->head = head;list->tail = tail;list->size = 0;// 关系list->head->next = list->tail;list->tail->prev = list->head;// 返回return list;
}// 释放双向链表内存
void freeDoubleLinkedList(DoubleLinkedList *list) {// 释放节点内存DoubleLinkedListNode *node = list->head->next;while (node->next != list->tail) {DoubleLinkedListNode *next = node->next;free(node);node = next;}// 释放首尾节点的内存free(list->head);free(list->tail);// 释放链表内存free(list);
}// 判断是否为空链表
int isEmptyDoubleLinkedList(DoubleLinkedList *list) {return list != NULL && list->head->next == list->tail;
}// 获取链表的元素个数
int sizeDoubleLinkedList(DoubleLinkedList *list) {return list->size;
}// 打印链表的内容
void printDoubleLinkedList(DoubleLinkedList *list) {if (list == NULL) {return;}if (list->head == NULL || list->head->next == NULL) {return;}DoubleLinkedListNode *current = list->head->next;while (current != list->tail) {printf("%d ", current->data);current = current->next;}printf("\n");
}// 将元素添加到链表末尾
void appendDoubleLinkedList(DoubleLinkedList *list, int value) {if (list == NULL || list->head == NULL || list->tail == NULL) {return;}// 构造新节点DoubleLinkedListNode *node = newDoubleLinkedListNode(value);// 插入到末尾DoubleLinkedListNode *oldPrev = list->tail->prev;oldPrev->next = node;node->prev = oldPrev;node->next = list->tail;list->tail->prev = node;// 元素个数增加list->size++;
}
main.c
#include "double_linked_list.h"int main(void) {// 创建链表DoubleLinkedList *list = newDoubleLinkedList();// 添加数据appendDoubleLinkedList(list, 11);printDoubleLinkedList(list);appendDoubleLinkedList(list, 22);printDoubleLinkedList(list);appendDoubleLinkedList(list, 33);printDoubleLinkedList(list);// 释放链表freeDoubleLinkedList(list);return 0;
}
输出:
11
11 22
11 22 33
移除元素
核心代码:
int removeDoubleLinkedList(DoubleLinkedList *list, int value) {int index = -1;if (list == NULL || list->head == NULL || list->tail == NULL || list->size <= 0) {return index;}// 查找对应的元素DoubleLinkedListNode *current = list->head->next;while (current != list->tail) {index++;if (current->data == value) {break;}current = current->next;}// 如果找到了,则删除if (index >= 0 && index < list->size) {DoubleLinkedListNode *oldPrev = current->prev;DoubleLinkedListNode *oldNext = current->next;oldPrev->next = oldNext;oldNext->prev = oldPrev;free(current); // 记得释放节点的内存}// 元素个数减少list->size--;// 返回return index;
}
double_linked_list.h
#ifndef ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
#define ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H// 公共头文件
#include "stdio.h"
#include "string.h"
#include "stdlib.h"// 双向链表的节点
typedef struct doubleLinkedListNode {int data;struct doubleLinkedListNode *next; // 下一个节点struct doubleLinkedListNode *prev; // 上一个节点
} DoubleLinkedListNode;// 双向链表
typedef struct doubleLinkedList {DoubleLinkedListNode *head; // 头节点DoubleLinkedListNode *tail; // 尾节点int size; // 节点的个数
} DoubleLinkedList;extern DoubleLinkedList *newDoubleLinkedList(); // 创建双向链表
extern void freeDoubleLinkedList(DoubleLinkedList *list); // 释放双向链表内存
extern int isEmptyDoubleLinkedList(DoubleLinkedList *list); // 判断是否为空链表
extern int sizeDoubleLinkedList(DoubleLinkedList *list); // 获取链表的元素个数
extern void printDoubleLinkedList(DoubleLinkedList *list); // 打印链表的内容
extern void appendDoubleLinkedList(DoubleLinkedList *list, int value); // 将元素添加到链表末尾
extern int removeDoubleLinkedList(DoubleLinkedList *list, int value); // 从链表中移除元素,成功返回其索引,失败返回-1#endif //ZDPC_ALGORITHM_DEV_DOUBLE_LINKED_LIST_H
double_linked_list.c
#include "double_linked_list.h"// 创建头节点
DoubleLinkedListNode *newDoubleLinkedListNode(int value) {// 申请节点的空间DoubleLinkedListNode *node = malloc(sizeof(DoubleLinkedListNode));// 初始化node->next = NULL;node->prev = NULL;node->data = value;// 返回return node;
}// 创建双向链表
DoubleLinkedList *newDoubleLinkedList() {// 申请链表的内存DoubleLinkedList *list = malloc(sizeof(DoubleLinkedList));// 头节点DoubleLinkedListNode *head = newDoubleLinkedListNode(0);// 尾结点DoubleLinkedListNode *tail = newDoubleLinkedListNode(0);// 初始化list->head = head;list->tail = tail;list->size = 0;// 关系list->head->next = list->tail;list->tail->prev = list->head;// 返回return list;
}// 释放双向链表内存
void freeDoubleLinkedList(DoubleLinkedList *list) {// 释放节点内存DoubleLinkedListNode *node = list->head->next;while (node->next != list->tail) {DoubleLinkedListNode *next = node->next;free(node);node = next;}// 释放首尾节点的内存free(list->head);free(list->tail);// 释放链表内存free(list);
}// 判断是否为空链表
int isEmptyDoubleLinkedList(DoubleLinkedList *list) {return list != NULL && list->head->next == list->tail;
}// 获取链表的元素个数
int sizeDoubleLinkedList(DoubleLinkedList *list) {return list->size;
}// 打印链表的内容
void printDoubleLinkedList(DoubleLinkedList *list) {if (list == NULL) {return;}if (list->head == NULL || list->head->next == NULL) {return;}DoubleLinkedListNode *current = list->head->next;while (current != list->tail) {printf("%d ", current->data);current = current->next;}printf("\n");
}// 将元素添加到链表末尾
void appendDoubleLinkedList(DoubleLinkedList *list, int value) {if (list == NULL || list->head == NULL || list->tail == NULL) {return;}// 构造新节点DoubleLinkedListNode *node = newDoubleLinkedListNode(value);// 插入到末尾DoubleLinkedListNode *oldPrev = list->tail->prev;oldPrev->next = node;node->prev = oldPrev;node->next = list->tail;list->tail->prev = node;// 元素个数增加list->size++;
}// 从链表中移除元素
int removeDoubleLinkedList(DoubleLinkedList *list, int value) {int index = -1;if (list == NULL || list->head == NULL || list->tail == NULL || list->size <= 0) {return index;}// 查找对应的元素DoubleLinkedListNode *current = list->head->next;while (current != list->tail) {index++;if (current->data == value) {break;}current = current->next;}// 如果找到了,则删除if (index >= 0 && index < list->size) {DoubleLinkedListNode *oldPrev = current->prev;DoubleLinkedListNode *oldNext = current->next;oldPrev->next = oldNext;oldNext->prev = oldPrev;free(current); // 记得释放节点的内存}// 元素个数减少list->size--;// 返回return index;
}
main.c
#include "double_linked_list.h"int main(void) {// 创建链表DoubleLinkedList *list = newDoubleLinkedList();// 添加数据appendDoubleLinkedList(list, 11);appendDoubleLinkedList(list, 22);appendDoubleLinkedList(list, 33);printDoubleLinkedList(list);printf("元素个数:%d\n",list->size);// 删除数据removeDoubleLinkedList(list,22);printDoubleLinkedList(list);printf("元素个数:%d\n",list->size);// 释放链表freeDoubleLinkedList(list);return 0;
}
输出:
11 22 33
元素个数:3
11 33
元素个数:2