C 语言方式实现了 双向链表的
插入
删除
查找
头部出栈
尾部出栈
头部插入
尾部插入
#include <stdio.h>
#include <stdlib.h>
typedef int bool;
typedef struct Node {
struct Node * front;
struct Node * back;
int data;
}Node;
typedef struct List {
struct Node * begin;// 第一个元素
struct Node * end; // 最后一个元素的后一个元素
}List;
// 使用链表前必须 调用Init
void Init(struct List * list) {
struct Node * node = (struct Node*)malloc(sizeof(struct Node));
node->front = NULL;
node->back = NULL;
// 当链表为空时预留一个元素(只是为了增加效率和设计上的方便)
list->begin = node;
list->end = list->begin;
}
bool IsEmpty(struct List * list) {
return list->end == list->begin;
}
// 在链表中从头到尾 查找第一个数据为data 的节点
struct Node* SearchList(struct List * list, int data) {
for(struct Node* p=list->begin; p != list->end; p=p->back) {
if(p->data == data) return p;
}
return NULL;
}
void PushFront(struct List * list, int data) {
struct Node * node = (struct Node*)malloc(sizeof(struct Node));
node->data = data;
node->front = NULL;
node->back = list->begin;
list->begin->front= node;
list->begin = node;
}
void PushBack(struct List * list, int data) {
list->end->data = data;
struct Node * node = (struct Node*)malloc(sizeof(struct Node));
node->back = NULL;
node->front = list->end;
list->end->back = node;
list->end = node;
}
int PopFront(struct List * list) {
int result = list->begin->data;
struct Node * p = list->begin;
list->begin = list->begin->back;
list->begin->front = NULL;
free(p);
return result;
}
int PopBack(struct List * list) {
struct Node * last = list->end->front;
int result = last->data;
struct Node * p = list->end;
last->back = NULL;
list->end = last;
free(p);
return result;
}
// 在节点 pos 后插入一个节点 数据为data
void InsertNodeTo(struct List * list, struct Node* pos, int data) {
struct Node * node = (struct Node*)malloc(sizeof(struct Node));
node->data = data;
node->front = pos;
node->back = pos->back;
pos->back = node;
node->back->front = node;
if(list->end == pos)
list->end = pos;
}
// 删除 list 中 pos 节点 (end 前一个元素是最后一个元素,不能删除 end 因为 end 是辅助节点不用于存储)
void RemoveNodeFrom(struct List * list, struct Node* pos) {
if(pos == list->begin) PopFront(list);
else if(pos == list->end->front) PopBack(list);
else {
pos->front->back = pos->back;
pos->back->front = pos->front;
free(pos);
}
}
void PrintList(struct List * list) {
for(struct Node* p=list->begin; p != list->end; p=p->back) {
printf("%d ", p->data);
}
printf("\n");
}
// 使用完需要使用Destroy将内存释放
void Destroy(struct List * list) {
struct Node* back;
for(struct Node* p=list->begin; p != list->end; p=back) {
back = p->back;
free(p);
}
if(list->end != NULL) free(list->end);
}
int main(void)
{
List list;
Init(&list);
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PushBack(&list, 5);
PushFront(&list, 0);
Node * pos = SearchList(&list, 3);
InsertNodeTo(&list, pos, 9);
PrintList(&list);
printf("Pop front %d\n", PopFront(&list));
printf("Pop back %d\n", PopBack(&list));
RemoveNodeFrom(&list, list.begin);
struct Node* p;
for(p=list.end->front; p!=list.begin; p=p->front) {
printf("%d ", p->data);
}
printf("%d\n", p->data);
Destroy(&list);
return 0;
}