双向链表
1. 双向链表的定义
双向带头循环链表
typedef struct ListNode
{
LTDataType data;
struct ListNode *prev;
struct ListNode *next;
}LTNode;
2. 链表初始化
LTNode* ListInit()
{
LTNode* phead = (LTNode*)malloc(sizeof(LTNode));
phead->next = phead;
phead->prev = phead;
return phead;
};
3. 创建新的节点
LTNode* BuyListNode(LTDataType x)
{
LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
newnode->data = x;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
};
4. 尾插
void ListPushBack(LTNode* phead,LTDataType x)
{
assert(phead);
LTNode* tail = phead->prev;
LTNode* newnode =(LTNode*)malloc(sizeof(LTNode));
newnode->data = x;
tail->next = newnode;
newnode->prev = tail;
newnode->next = phead;
phead->prev = newnode;
};
5. 头插
void ListPushFront(LTNode* phead,LTDataType x)
{
assert(phead != NULL);
LTNode* newnode = BuyListNode(x);
LTNode* tail = phead->next;
phead->next = newnode;
newnode->prev = phead;
newnode->next = tail;
tail->prev = newnode;
};
6. 尾删
void ListPopBack(LTNode* phead)
{
assert(phead != NULL);
assert(phead->next != phead);
LTNode* tail = phead->prev;
LTNode* tailprev = tail->prev;
free(tail);
tailprev->next = phead;
phead->prev = tailprev;
};
7. 头删
void ListPopFront(LTNode* phead)
{
assert(phead != NULL);
assert(phead->next != phead);
LTNode* tail = phead->next;
LTNode* next = tail->next;
free(tail);
phead->next = next;
next->prev = phead;
};
8. pos位置删除
void ListErase(LTNode* pos)
{
assert(pos != NULL);
LTNode* posPrev = pos->prev;
LTNode* posNext = pos->next;
free(pos);
posPrev->next = posNext;
posNext->prev = posPrev;
};
9. 查找
LTNode* ListFind(LTNode* phead,LTDataType x)
{
assert(phead);
LTNode* cur = phead->next;
while(cur != phead)
{
if(cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
};
10. pos位置之前插入
void ListInsert(LTNode* pos,LTDataType x)
{
assert(pos != NULL);
LTNode* posPrev = pos->prev;
LTNode* newnode = BuyListNode(x);
posPrev->next = newnode;
newnode->prev = posPrev;
newnode->next = pos;
pos->prev = newnode;
};
11. pos位置删除
void ListErase(LTNode* pos)
{
assert(pos != NULL);
LTNode* posPrev = pos->prev;
LTNode* posNext = pos->next;
posPrev->next = posNext;
posNext->prev = posPrev;
free(pos);
};
12.双向链表的销毁
void ListDestroy(LTNode* phead)
{
assert(phead != NULL);
LTNode* cur = phead->next;
while(cur != phead)
{
LTNode* next = cur->next;
free(cur);
cur = next;
}
free(phead);
};
用完Destroy后要将传过来的指针手动置空,这是因为要保证传参结构的一致性(都是传一级指针),如果要在Destroy内置空,要用二级指针实现。