我们对此分为三个文件,两个源文件DList.c main.c 和一个头文件SList.h
DList.h 中用来包含头文件,定义结构体,和对函数的声明;DList.c 中写对函数的实现; main.c 中是主函数和测试函数
"DList.h"
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int DLDataType;
typedef struct DListNode {
DLDataType val;
struct DListNode *next;
struct DListNode *prev;
}DListNode;
typedef struct DList {
struct DListNode *head;
}DList;
// 内部接口
DListNode * BuyNode(DLDataType val);
// 初始化
void DListInit(DList * dlist);
// 清空(只是删除链表中有实际意义的节点。并没有删除头节点)
void DListClear(DList *dlist);
// 销毁(头结点都没有了,是个无效链表)
void DListDestroy(DList *dlist);
// 增删改查
// 在 pos 结点前面做插入
void DListInsert(DListNode *pos, DLDataType val);
// 头插
void DListPushFront(DList *dlist, DLDataType val);
// 尾插
void DListPushBack(DList *dlist, DLDataType val);
// 查找
// 找到第一个 val 的结点,返回结点地址
// 如果没找到,返回 NULL
DListNode * DListFind(DList *dlist, DLDataType val);
// 删除 pos 结点,pos 不是头结点
void DListErase(DListNode *pos);
//头删
void DListPopFront(DList *dlist);
//尾删
void DListPopBack(DList *dlist);
// 打印
void DListPrintByHead(DListNode *head);//传头节点地址打印
void DListPrintByDList(DList *dlist);//传链表地址打印
"DList.c"
#include"DList.h"
//创建节点
DListNode * BuyNode(DLDataType val)
{
DListNode *node = (DListNode *)malloc(sizeof(DListNode));
assert(node);
node->val = val;
node->next = node->prev = NULL;
return node;
}
//链表初始化
void DListInit(DList * dlist)
{
//创建头节点
DListNode *head = BuyNode(0);// 头节点中val无意义(有时会被用来存放链表长度)
// 此处val是无意义,并没有存放链表长度
head->next = head->prev = head;
dlist->head = head;
}
//清空链表
void DListClear(DList *dlist)
{
DListNode *cur, *next;
for (cur = dlist->head->next; cur != dlist->head; cur = next)
{
next = cur->next;
free(cur);
}
dlist->head->next = dlist->head->prev = dlist->head;
}
//销毁
void DListDestroy(DList *dlist)
{
DListClear(dlist);
// 指针free之后,free函数只是把指针指向的内存空间释放了,即内存中存储的值,
// 但是并没有将指针的值赋为NULL,指针仍然指向这块内存。
free(dlist->head);
dlist->head = NULL;
}
// 在 pos 结点前面做插入
void DListInsert(DListNode *pos, DLDataType val)
{
//申请新节点
DListNode *node = BuyNode(val);
//插入
node->prev = pos->prev;
node->next = pos;
pos->prev->next = node;
pos->prev = node;
}
// 头插
void DListPushFront(DList *dlist, DLDataType val)
{
DListInsert(dlist->head->next, val);
#if 0
//创建一个节点
DListNode *node = BuyNode(val);
//插入
node->prev = dlist->head;
node->next = dlist->head->next;
dlist->head->next->prev = node;
dlist->head->next = node;
#endif
}
// 尾插
void DListPushBack(DList *dlist, DLDataType val)
{
DListInsert(dlist->head, val);
#if 0
//创建一个节点
DListNode *node = BuyNode(val);
//插入
node->prev = dlist->head->prev;
node->next = dlist->head;
dlist->head->prev->next = node;
dlist->head->prev = node;
#endif
}
// 查找
//(找到第一个 val 的结点,返回结点地址; 如果没找到,返回 NULL)
DListNode * DListFind(DList *dlist, DLDataType val)
{
assert(dlist->head);
for (DListNode *cur = dlist->head->next; cur != dlist->head; cur = cur->next)
{
if (cur->val == val)
{
return cur;
}
}
return NULL;
}
// 删除 pos 结点,pos 不是头结点
void DListErase(DListNode *pos)
{
assert(pos);
pos->prev->next = pos->next;
pos->next->prev = pos->prev;
free(pos);
}
void DListPopFront(DList *dlist)
{
assert(dlist->head->next != dlist->head);
DListErase(dlist->head->next);
}
void DListPopBack(DList *dlist)
{
assert(dlist->head->next != dlist->head);
DListErase(dlist->head->prev);
}
// 打印
void DListPrintByHead(DListNode *head)//传头节点地址打印
{
assert(head);
for (DListNode *cur = head->next; cur != head; cur = cur->next)
{
printf("%d->",cur->val);
}
printf("\n");
}
void DListPrintByDList(DList *dlist)//传链表地址打印
{
assert(dlist);
assert(dlist->head);
DListPrintByHead(dlist->head);
}
"main.c"
#include"DList.h"
void test()
{
DList dlist;
DListInit(&dlist);
//DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
//printf("%p", DListFind(&dlist, 0));
DListPushFront(&dlist, 3);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListPushFront(&dlist, 2);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListPushFront(&dlist, 1);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListPushBack(&dlist, 11);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListPushBack(&dlist, 12);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListPushBack(&dlist, 13);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListNode *pos = DListFind(&dlist, 2);
DListErase(pos);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListNode *pos1 = DListFind(&dlist, 3);
DListInsert(pos1, 2);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListPopFront(&dlist);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListPopFront(&dlist);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListPopFront(&dlist);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListPopBack(&dlist);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListPopBack(&dlist);
DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListClear(&dlist);
//DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
DListDestroy(&dlist);
//DListPrintByDList(&dlist);
//DListPrintByHead(dlist.head);
}
int main()
{
test();
system("pause");
return 0;
}
以上"main.c"中为个人的测试代码,可以根据自己的喜好设置测试代码,这里给出测试代码仅供参考。