这篇文章写的是双向循环链表,这也是个非常经典的数据结构,我们在看 Linux 内核代码时就经常会遇到它。比如,在Linux的内核中实现进程描述符,使用的就是双向循环链表,因为它使用起来很方便,每个节点不只是有 data 字段,还有 prev , next 字段,对于向前和向后查找相应的节点很方便,下面贴出实现代码,仍然是很简单的操作,且没有过多的错误控制:
头文件:
/* * dlut_dclist.h * * Created on: 2014年1月13日 * Author: DLUTBruceZhang */ #ifndef DLUT_DCLIST_H_ #define DLUT_DCLIST_H_ typedef int need; typedef struct _dclist { need data; struct _dclist *next; struct _dclist *prev; }dclist; dclist * dlut_dclist_create(); void dlut_dclist_insert_to_head(dclist *, need); void dlut_dclist_insert_to_tail(dclist *, need); void dlut_dclist_delete_the_head(dclist *); void dlut_dclist_delete_the_tail(dclist *); void dlut_dclist_delete_the_data(dclist *, need); need dlut_dclist_get_the_head(dclist *); need dlut_dclist_get_the_tail(dclist *); void dlut_dclist_print_the_dclist(dclist *); void dlut_dclist_delete_the_dclist(dclist *); #endif /* DLUT_DCLIST_H_ */
C文件:
/* * dlut_dclist.c * * Created on: 2014年1月13日 * Author: DLUTBruceZhang */ #include "dlut_dclist.h" #include <stdlib.h> #include <stdio.h> dclist * dlut_dclist_create() { dclist *head; head = (dclist *)malloc(sizeof(dclist)); if (!head) return NULL; head -> data = 0; head -> next = head; head -> prev = head; return head; } void dlut_dclist_insert_to_head(dclist *head, need data) { dclist *new_node; new_node = (dclist *)malloc(sizeof(dclist)); if (!new_node) return; new_node -> data = data; new_node -> next = head -> next; head -> next -> prev = new_node; head -> next = new_node; new_node -> prev = head; head -> data += 1; return; } void dlut_dclist_insert_to_tail(dclist *head, need data) { dclist *new_node; new_node = (dclist *)malloc(sizeof(dclist)); if (!new_node) return; new_node -> data = data; dclist *_head = head; while (_head -> next != head) _head = _head -> next; new_node -> next = head; head -> prev = new_node; new_node -> prev = _head; _head -> next = new_node; head -> data += 1; return; } void dlut_dclist_delete_the_head(dclist *head) { dclist *old_node; if (head -> next == head) return; old_node = head -> next; head -> next -> next -> prev = head; head -> next = head -> next -> next; head -> data -= 1; free(old_node); return; } void dlut_dclist_delete_the_tail(dclist *head) { dclist *old_node; if (head -> next == head) return; dclist *_head = head; while (_head -> next != head) _head = _head -> next; old_node = _head; _head -> prev -> next = head; head -> prev = _head -> prev; head -> data -= 1; free(old_node); return; } void dlut_dclist_delete_the_data(dclist *head, need data) { if (head -> next == head) return; dclist *_head = head; while (_head -> data != data && _head -> next != head) _head = _head -> next; if (_head -> data == data) { _head -> prev -> next = _head -> next; _head -> next -> prev = _head -> prev; head -> data -= 1; } return; } need dlut_dclist_get_the_head(dclist *head) { return head -> data == 0 ? -1 : head -> next -> data; } need dlut_dclist_get_the_tail(dclist *head) { return head -> data == 0 ? -1 : head -> prev -> data; } void dlut_dclist_print_the_dclist(dclist *head) { dclist *_head = head -> next; while (_head != head) { printf("%d ", _head -> data); _head = _head -> next; } printf("\n"); return; } void dlut_dclist_delete_the_dclist(dclist *head) { while (head -> next != head) dlut_dclist_delete_the_head(head); free(head); return; }