数据结构--带头双向循环链表的基本功能实现
程序员文章站
2022-03-15 19:41:08
...
带头双向循环链表 : 是一种无死角链表, 是链表的一种,带有头结点, 其次它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点 , 且它的头指向尾 , 尾指向头 , 是循环的 , 是双向的 , 是带头结点的 ,
基本结构如下图所示 :
List.h
#pragma once
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <assert.h>
typedef int LTDataType;
//链表结构体
typedef struct ListNode
{
struct ListNode* _next;
struct ListNode* _prev;
LTDataType _data;
}ListNode;
typedef struct List
{
struct ListNode* _head;
}List;
//初始化链表
void ListInit(List* lt);
//销毁链表
void ListDestory(List* lt);
//头插
void ListPushFront(List* lt, LTDataType x);
//尾插
void ListPushBack(List* lt, LTDataType x);
//头删
void ListPopFront(List* lt);
//尾删
void ListPopBack(List* lt);
//申请节点
ListNode* BuyListNode();
//查找节点
ListNode* ListFind(List* lt, LTDataType x);
//指定位置插入
void ListInsert(ListNode* pos, LTDataType x);
//指定位置删除
void ListErase(ListNode* pos);
//链表大小
int ListSize(List* lt);
//判断链表是否为空
int ListEmpty(List* lt);
//打印链表
void ListPrint(List* lt);
List.c
#include "List.h"
//初始化链表
void ListInit(List* lt)
{
//创建头结点
lt->_head = BuyListNode();
lt->_head->_next = lt->_head;
lt->_head->_prev = lt->_head;
}
//销毁链表
void ListDestory(List* lt)
{
ListNode *del,*ret;
assert(lt);
del = lt->_head->_next;
while (del == lt->_head)
{
ret = del;
free(ret);
ret = NULL;
del = del->_next;
}
free(del);
del = NULL;
}
//头插
void ListPushFront(List* lt, LTDataType x)
{
assert(lt);
//相当于在头结点后面插入
ListInsert(lt->_head->_next, x);
}
//尾插
void ListPushBack(List* lt, LTDataType x)
{
assert(lt);
//相当于在头结点前面插入
ListInsert(lt->_head->_prev, x);
}
//头删
void ListPopFront(List* lt)
{
assert(lt);
//相当于删除头结点后面的元素
ListErase(lt->_head->_prev);
}
//尾删
void ListPopBack(List* lt)
{
assert(lt);
//相当于删除头结点前面的元素
ListErase(lt->_head->_next);
}
//申请节点
ListNode* BuyListNode()
{
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
//断言,空间是否开辟成功
assert(newNode);
newNode->_next = NULL;
newNode->_prev = NULL;
return newNode;
}
//查找节点
ListNode* ListFind(List* lt, LTDataType x)
{
ListNode * newNode;
assert(lt);
newNode = lt->_head;
while (newNode->_next != lt->_head)
{
newNode=newNode->_next;
if (newNode->_data == x)
return newNode;
}
printf("要查找的数据 %d 不存在!\n",x);
return NULL;
}
//指点位置插入
void ListInsert(ListNode* pos, LTDataType x)
{
ListNode *prev;
ListNode *newNode;
if (!pos)
{
printf("数据 %d 插入失败!\n", x);
return;
}
newNode = BuyListNode();
newNode->_data = x;
prev = pos->_prev;
prev->_next = newNode;
newNode->_prev = prev;
newNode->_next = pos;
pos->_prev = newNode;
}
//指点位置删除
void ListErase(ListNode* pos)
{
ListNode *prev;
prev = pos->_prev;
prev->_next = pos->_next;
pos->_next->_prev = prev;
free(pos);
pos = NULL;
}
//链表大小
int ListSize(List* lt)
{
ListNode *cur;
int size = 0;
assert(lt);
assert(lt);
cur = lt->_head;
while (cur->_next != lt->_head)
{
cur = cur->_next;
size++;
}
return size;
}
//判断链表是否为空
int ListEmpty(List* lt)
{
assert(lt);
//为空返回0,非空返回1
return lt->_head->_next == lt->_head->_prev ? 0 : 1;
}
//打印链表
void ListPrint(List* lt)
{
ListNode *cur;
assert(lt);
cur = lt->_head;
printf("链表中的数据为: ");
while (cur->_next != lt->_head)
{
printf("%d ", cur->_next->_data);
cur = cur->_next;
}
printf("\n");
}
test.c
#include "List.h"
int main()
{
List lt;
ListNode *cur;
ListInit(<);
ListPushBack(<, 1);
ListPushBack(<, 2);
ListPushBack(<, 3);
ListPushBack(<, 4);
cur = ListFind(<, 3);
ListErase(cur);
cur = ListFind(<, 4);
ListInsert(cur, 5);
printf("链表的长度为: %d\n", ListSize(<));
ListPrint(<);
ListDestory(<);
system("pause");
return 0;
}
下一篇: java面试题(三)