一、带头双向链表与无头单链表比较
- 带头双向链表:可以找到前驱后驱,增删复杂,多一个指针存储空间
- 无头单链表:只能找到前驱,增删简单
二、源代码
一、list.h
#ifndef _LIST__H_
#define _LIST__H_
#include "stdio.h"
#include "assert.h"
#include "malloc.h"
#include "string.h"
typedef int DataType;
typedef struct ListNode
{
struct ListNode* _next;
struct ListNode* _prev;
DataType _data;
}List, *pList;
void ListInit(pList* lt);
void ListDestory(pList* lt);
pList BuyListNode(DataType x);
void ListPushBack(pList* lt, DataType x);
void ListPushFront(pList* lt, DataType x);
void ListPopBack(pList* lt);
void ListPopFront(pList* lt);
pList ListFind(pList lt, DataType x);
void ListInsert(pList* pos, DataType x);
void ListErase(pList* pos);
int ListSize(pList lt);
int ListEmpty(pList lt);
void ListPrint(pList lt);
#endif
二、list.c
#include "list.h"
//初始化双向链表
void ListInit(pList* lt)
{
assert(lt);
(*lt) = (pList)malloc(sizeof(List));
(*lt)->_next = NULL;
(*lt)->_prev = NULL;
(*lt)->_next = *lt;
(*lt)->_prev = *lt;
}
//清除双向链表
void ListDestory(pList* lt)
{
assert(lt);
pList list = *lt;
while (list->_next != (*lt))
{
pList tmp = list;
list = list->_next;
free(tmp);
tmp = NULL;
}
*lt = NULL;
}
//创建新结点
pList BuyListNode(DataType x)
{
pList node = (pList)malloc(sizeof(List));
node->_data = x;
node->_next = NULL;
node->_prev = NULL;
return node;
}
//尾插
void ListPushBack(pList* lt, DataType x)
{
assert(lt);
ListInsert(lt, x);
}
//头插
void ListPushFront(pList* lt, DataType x)
{
assert(lt);
ListInsert(&(*lt)->_next, x);
}
//尾删
void ListPopBack(pList* pos)
{
assert(pos);
pList list = (*pos)->_prev->_prev;
if ((*pos)->_next == (*pos))
return;
(*pos)->_prev = list;
free(list->_next);
list->_next = *pos;
}
//头删
void ListPopFront(pList* pos)
{
assert(pos);
pList list = (*pos)->_next->_next;
if ((*pos)->_next == (*pos))
return;
list->_prev = *pos;
free((*pos)->_next);
(*pos)->_next = list;
}
//找出指定元素
pList ListFind(pList lt, DataType x)
{
assert(lt);
pList list = lt->_next;
while (list != lt)
{
if (list->_data == x)
return list;
list = list->_next;
}
return NULL;
}
//插入指定元素
void ListInsert(pList* pos, DataType x)
{
assert(pos);
pList node = BuyListNode(x);
pList list = (*pos)->_prev;
(*pos)->_prev = node;
node->_next = *pos;
list->_next = node;
node->_prev = list;
}
//删除
void ListErase(pList* pos)
{
assert(pos);
ListPopBack(pos);
}
//双向链表长
int ListSize(pList lt)
{
assert(lt);
int count = 0;
pList list = lt;
while (list->_next != lt)
{
count++;
list = list->_next;
}
return count;
}
//判断双向链表是否为空
int ListEmpty(pList lt)
{
assert(lt);
if (lt->_next == lt)
return 0;
return 1;
}
//打印双向链表
void ListPrint(pList lt)
{
assert(lt);
pList list = lt->_next;
while (list->_next != lt)
{
printf("%d ", list->_data);
list = list->_next;
}
printf("%d\n",list->_data);
}
三、写一个测试(test.c)让代码跑起来并加以验证