List.c
#include "List.h"
LTNode* BuyListNode(LTDataType x)
{
LTNode* node = (LTNode*)malloc(sizeof(LTNode));
if (node == NULL)
{
perror("malloc fail");
exit(-1);//终止程序
return;
}
node->next = NULL;
node->prev = NULL;
node->data = x;
return node;
}
LTNode* ListInit()
{
LTNode* phead = BuyListNode(-1);
phead->next = phead;
phead->prev = phead;
return phead;
}
//void ListInit(LTNode** pphead)
//{
// *pphead = BuyListNode(-1);
// (*pphead)->next = *pphead;
// (*pphead)->prev = *pphead;
//}
void ListPrint(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;
while (cur != phead)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
//尾插
void ListPushBack(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode* newnode = BuyListNode(x);
LTNode* tail = phead->prev;
tail->next = newnode;
newnode->prev = tail;
newnode->next = phead;
phead->prev = newnode;
//注意!
//可以用任意插==>哨兵位前一个就是尾节点
//ListInsert(phead, x);
}
//头插
void ListPushFront(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode* newnode = BuyListNode(x);
LTNode* next = phead->next;//后面就不需要考虑顺序了
// phead newnode next
next->prev = newnode;
newnode->next = next;
newnode->prev = phead;
phead->next = newnode;
//注意!如果不写next,有严格的顺序
// phead->next->prev = newnode;
// newnode->next = phead->next;前两句不能换
// phead->next = newnode;
// newnode->prev = phead;
//再注意!
//可以直接用任意插
//ListInsert(phead->next, x);
}
//检查是否为空(只有哨兵位)
bool ListEmpty(LTNode* phead)
{
assert(phead);
return phead->next == phead;
}
//尾删
void ListPopBack(LTNode* phead)
{
assert(phead);
assert(!ListEmpty(phead));//防止链表为空
//assert(phead->next != phead);
LTNode* tail = phead->prev;
LTNode* tailPrev = tail->prev;
free(tail);
tailPrev->next = phead;
phead->prev = tailPrev;
//再注意!
//可以直接用任意删
//ListErase(phead->prev);
}
//头删
void ListPopFront(LTNode* phead)
{
assert(phead);
assert(!ListEmpty(phead));//防止链表为空
//assert(phead->next != phead);
LTNode* top = phead->next;
phead->next = top->next;
top->next->prev = phead;
free(top);
//再注意!
//可以直接用任意删
//ListErase(phead->next);
}
//在pos位置之前插入x
void ListInsert(LTNode* pos, LTDataType x)
{
assert(pos);
LTNode* prev = pos->prev;
LTNode* newnode = BuyListNode(x);
// prev newnode pos
prev->next = newnode;
newnode->prev = prev;
newnode->next = pos;
pos->prev = newnode;
}
//删除pos位置的节点
void ListErase(LTNode* pos)
{
assert(pos);
LTNode* prev = pos->prev;
LTNode* next = pos->next;
prev->next = next;
next->prev = prev;
free(pos);
}
//数元素
int ListSize(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;
int size = 0;
while (cur != phead)//循环回去就结束了
{
++size;
cur = cur->next;
}
return size;
}
//双向链表销毁
void ListDestory(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;
int size = 0;
while (cur != phead)//循环回去就结束了
{
LTNode* next = cur->next;
ListErase(cur);
cur = next;
}
free(phead);
phead = NULL;//好习惯
}
List.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
//带头(哨兵位)双向循环链表
typedef int LTDataType;
typedef struct ListNode
{
struct ListNode* next;
struct ListNode* prev;
LTDataType data;
}LTNode;
//void ListInit(LTNode** pphead);太复杂了
//初始化
LTNode* ListInit();
//打印
void ListPrint(LTNode* phead);
//尾插头插
void ListPushBack(LTNode* phead, LTDataType x);
void ListPushFront(LTNode* phead, LTDataType x);
//检查是否为空(只有哨兵位)
bool ListEmpty(LTNode* phead);
//尾删头删
void ListPopBack(LTNode* phead);
void ListPopFront(LTNode* phead);
//上来先写这个!!!!!!!
//在pos位置之前插入x
void ListInsert(LTNode* pos, LTDataType x);
//删除pos位置的节点
void ListErase(LTNode* pos);
//数元素
int ListSize(LTNode* phead);
//双向链表销毁
void ListDestory(phead);