typedef int LTDateType;
typedef struct ListNode//双向循环链表结点
{
LTDateType val;
struct ListNode* next;
struct ListNode* prev;
}LTNode;
//创建一个哨兵位的头结点,并返回地址
LTNode* ListInit()
{
LTNode* phead = (LTNode*)malloc(sizeof(LTNode));
phead->next = phead;//尾指向头
phead->prev = phead;//头指向尾
return phead;
}
//打印
void ListPrint(LTNode* phead)
{
assert(phead);
//phead为哨兵位的头结点,打印从phead->next指向的结点开始
//尾节点的next指向的是哨兵位的头结点,遇到头结点停止打印
LTNode* cur = phead->next;
while (cur != phead)
{
printf("%d ", cur->val);
cur = cur->next;
}
printf("\n");
}
//给插入元素x创建开辟一个结点
LTNode* BuyListNode(LTDateType x)
{
LTNode* newNode = (LTNode*)malloc(sizeof(LTNode));
newNode->val = x;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
//尾插
void ListPushBack(LTNode* phead, LTDateType x)
{
//结点不为NULL
assert(phead);
//phead指向尾部的结点地址赋给tail
LTNode* tail = phead->prev;
//给插入元素x创建开辟一个结点
LTNode* newNode = BuyListNode(x);
//结点尾插
tail->next = newNode;
newNode->prev = tail;
//头尾相连
phead->prev = newNode;
newNode->next = phead;
//引用ListInsert尾插
//ListInsert(phead->prev, x);
}
//尾删
void ListPopBack(LTNode* phead)
{
//指针不为空
assert(phead);
//哨兵位头结点指向的不是自己,保证链表内部有有效结点
assert(phead->next != phead);
//找到尾结点
LTNode* tail = phead->prev;
//修改尾结点的前一个结点,使之首尾循环
LTNode* tailPrev = tail->prev;
tailPrev->next = phead;
phead->prev = tailPrev;
//释放删除的尾结点空间内存
free(tail);
//引用ListErase尾删
ListErase(phead->prev);
}
//头插
void ListPushfront(LTNode* phead, LTDateType x)
{
//指针不为空
assert(phead);
//给插入元素x创建开辟一个结点
LTNode* newNode = BuyListNode(x);
//创建一个指针指向第一个有效头结点
LTNode* next = phead->next;
//与哨兵位链接
phead->next = newNode;
newNode->prev = phead;
//与头结点链接,称为新头结点
newNode->next = next;
next->prev = newNode;
//引用ListInsert头插
//ListInsert(phead->next, x);
}
//头删
void ListPopFront(LTNode* phead)
{
//指针不为空
assert(phead);
//哨兵位头结点指向的不是自己,保证链表内部有有效结点
assert(phead->next != phead);
//找到要删除的头部结点
LTNode* next = phead->next;
//找到要删除的头部结点的下一个结点
LTNode* nextNext = next->next;
//哨兵位与nextNext链接
phead->next = nextNext;
nextNext->prev = phead;
//释放删除的头结点的空间
free(next);
//引用ListErase头删
//ListErase(phead->next);
}
//查找
LTNode* ListFind(LTNode* phead, LTDateType x)
{
assert(phead);
//phead为哨兵位的头结点,查找从phead->next指向的结点开始
//尾节点的next指向的是哨兵位的头结点,遇到头结点停止查找
LTNode* cur = phead->next;
while (cur != phead)
{
if (cur->val == x)
{
return cur;//返回x所在的位置pos
}
cur = cur->next;
}
return NULL;
}
//指定位置前插入
void ListInsert(LTNode* pos, LTDateType x)
{
assert(pos);
//找到pos结点前一个结点
LTNode* posPrev = pos->prev;
//创建新结点
LTNode* newNode = BuyListNode(x);
//建立链接
posPrev->next = newNode;
newNode->prev = posPrev;
newNode->next = pos;
pos->prev = newNode;
}
//指定位置删除
void ListErase(LTNode* pos)
{
assert(pos);
//找到pos结点前一个结点
LTNode* posPrev = pos->prev;
//找到pos结点后一个结点
LTNode* posNext = pos->next;
//链接
posPrev->next = posNext;
posNext->prev = posPrev;
//释放pos结点空间
free(pos);
pos = NULL;
}
//销毁
void ListDestroy(LTNode* phead)
{
assert(phead);
//创建当前指针指向第一个有效结点
LTNode* cur = phead->next;
//开始销毁,直到cur指向哨兵位phead结点
while (cur != phead)
{
//记录cur结点的下一个结点
LTNode* next = cur->next;
//销毁
free(cur);
//cur迭代往后走
cur = next;
}
//只剩下最后的哨兵位,函数外部置空,即plist = NULL
}