带头双向链表

一、带头双向链表与无头单链表比较

  • 带头双向链表:可以找到前驱后驱,增删复杂,多一个指针存储空间
  • 无头单链表:只能找到前驱,增删简单

二、源代码

一、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)让代码跑起来并加以验证

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值