双链表

双向链表

1. 双向链表的定义

双向带头循环链表
title

1
2
3
4
5
6
typedef struct ListNode
{
LTDataType data;
struct ListNode *prev;
struct ListNode *next;
}LTNode;

2. 链表初始化

1
2
3
4
5
6
7
8
LTNode* ListInit()
{
LTNode* phead = (LTNode*)malloc(sizeof(LTNode));
phead->next = phead;
phead->prev = phead;

return phead;
};

3. 创建新的节点

1
2
3
4
5
6
7
8
9
LTNode* BuyListNode(LTDataType x)
{
LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
newnode->data = x;
newnode->next = NULL;
newnode->prev = NULL;

return newnode;
};

4. 尾插

1
2
3
4
5
6
7
8
9
10
11
12
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. 头插

1
2
3
4
5
6
7
8
9
10
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. 尾删

1
2
3
4
5
6
7
8
9
10
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. 头删

1
2
3
4
5
6
7
8
9
10
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位置删除

1
2
3
4
5
6
7
8
9
void ListErase(LTNode* pos)
{
assert(pos != NULL);
LTNode* posPrev = pos->prev;
LTNode* posNext = pos->next;
free(pos);
posPrev->next = posNext;
posNext->prev = posPrev;
};

9. 查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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位置之前插入

1
2
3
4
5
6
7
8
9
10
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位置删除

1
2
3
4
5
6
7
8
9
10
void ListErase(LTNode* pos)
{
assert(pos != NULL);
LTNode* posPrev = pos->prev;
LTNode* posNext = pos->next;

posPrev->next = posNext;
posNext->prev = posPrev;
free(pos);
};

12.双向链表的销毁

1
2
3
4
5
6
7
8
9
10
11
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内置空,要用二级指针实现。

Contents
  1. 1. 双向链表
    1. 1.1. 1. 双向链表的定义
    2. 1.2. 2. 链表初始化
    3. 1.3. 3. 创建新的节点
    4. 1.4. 4. 尾插
    5. 1.5. 5. 头插
    6. 1.6. 6. 尾删
    7. 1.7. 7. 头删
    8. 1.8. 8. pos位置删除
    9. 1.9. 9. 查找
    10. 1.10. 10. pos位置之前插入
    11. 1.11. 11. pos位置删除
    12. 1.12. 12.双向链表的销毁
|