C语言实现双链表
2016-03-21 09:22
417 查看
双链表一定要注意,前驱指针,Erase的时候,要判断next是否为NULL,要不然不能使用前驱指针
结点定义如下:
typedef int DataType;
typedef struct ListNode
{
DataType data;
ListNode* prev;
ListNode* next;
};
实现了的函数的声明如下:
具体实现如下:
测试用例如下:
因为Erase比较特殊,就只写这个的测试用例
void Test()
{
SListNode* list1 = NULL;
PushBack(&list1, 1);
PushBack(&list1, 2);
PushBack(&list1, 3);
PushBack(&list1, 4);
PushBack(&list1, 5);
PrintSlist(list1);
Erase(list1, list1->next);
PrintSlist(list1);
Erase(list1, list1->next);
PrintSlist(list1);
Erase(list1, list1->next);
PrintSlist(list1);
Erase(list1, list1->next);
PrintSlist(list1);
Erase(list1, list1);
PrintSlist(list1);
}
结点定义如下:
typedef int DataType;
typedef struct ListNode
{
DataType data;
ListNode* prev;
ListNode* next;
};
实现了的函数的声明如下:
ListNode* _BuyNode(DataType x); void PrintNode(ListNode* pHead); void PushBack(ListNode*& pHead, DataType x); void PopBack(ListNode*& pHead); void PushFront(ListNode*& pHead, DataType x); ListNode* Find(ListNode* pHead, DataType x); void Insert(ListNode*& pos, DataType x);//要分两种情况,要不然pos是尾的话,next->prev将崩溃 void Erase(ListNode*& pHead, ListNode* pos);//删除的时候,分条件:1.为头节点2.不为头节点
具体实现如下:
ListNode* _BuyNode(DataType x) { ListNode* tmp = (ListNode*)malloc(sizeof(ListNode)); tmp->data = x; tmp->next = NULL; tmp->prev = NULL; return tmp; } void PrintNode(ListNode* pHead) { ListNode* cur = pHead; while (cur != NULL) { printf("%d->", cur->data); cur = cur->next; } printf("NULL\n"); } void PushBack(ListNode*& pHead,DataType x) { if (pHead == NULL) { pHead = _BuyNode(x); return; } else { ListNode* cur = pHead; while (cur->next) { cur = cur->next; } ListNode* tmp = _BuyNode(x); cur->next = tmp; tmp->prev = cur; } } void PopBack(ListNode*& pHead) { if (pHead == NULL) { return; } else if (pHead->next == NULL)//上面的判断条件,已经保证这里不为pHead!=NULL { free(pHead); pHead = NULL; } else//看似第二个判断条件和第三个判断条件可以何为一个 { ListNode* tmp = pHead->next; free(pHead); pHead = tmp; tmp->prev = NULL;//但是这里会出问题 } } void PushFront(ListNode*& pHead, DataType x) { if (pHead == NULL) { pHead = _BuyNode(x); return; } else { ListNode* tmp = pHead; pHead = _BuyNode(x); pHead->next = tmp; tmp->prev = pHead; } } void PopFront(ListNode*& pHead) { if (pHead==NULL) { return; } else if (pHead->next == NULL) { free(pHead); pHead = NULL; } else { ListNode* tmp = pHead->next; free(pHead); pHead = tmp; pHead->prev = NULL; } } ListNode* Find(ListNode* pHead, DataType x) { ListNode* cur = pHead; while (cur) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL; } void Insert(ListNode*& pos, DataType x)//要分两种情况,要不然pos是尾的话,next->prev将崩溃 { assert(pos); ListNode* tmp = _BuyNode(x); if (pos->next == NULL) { pos->next = tmp; tmp->prev = NULL; } else { ListNode* next = pos->next; pos->next = tmp; tmp->prev = pos; tmp->next = next; next->prev = tmp; } } void Erase(ListNode*& pHead,ListNode* pos)//删除的时候,分条件:1.为头节点2.不为头节点 { assert(pHead); assert(pos); if (pHead == pos) { PopFront(pHead); } else { ListNode* cur = pHead; ListNode* prev = pHead; while (cur) { prev = cur; cur = cur->next; if (cur == pos) { ListNode* next = cur->next;//因为pos不为NULL所以保证cur不为NULL if (next == NULL)//双链表删除的时候,一定要判断是不是为尾节点,尾节点一定要注意前驱指针 { PopBack(pHead); } else { prev->next = next; next->prev = prev; free(cur); return; } } } } }
测试用例如下:
因为Erase比较特殊,就只写这个的测试用例
void Test()
{
SListNode* list1 = NULL;
PushBack(&list1, 1);
PushBack(&list1, 2);
PushBack(&list1, 3);
PushBack(&list1, 4);
PushBack(&list1, 5);
PrintSlist(list1);
Erase(list1, list1->next);
PrintSlist(list1);
Erase(list1, list1->next);
PrintSlist(list1);
Erase(list1, list1->next);
PrintSlist(list1);
Erase(list1, list1->next);
PrintSlist(list1);
Erase(list1, list1);
PrintSlist(list1);
}
相关文章推荐
- C数据结构之双链表详细示例分析
- 详解Redis中的双链表结构
- javascript数据结构之双链表插入排序实例详解
- PHP 双链表(SplDoublyLinkedList)简介和使用实例
- 双链表实现的消息队列,可支持优先级读取
- C语言一个双向链表的实现
- 线性表
- LRU缓存介绍与实现 (Java)
- bigint的一些小问题
- 双向链表
- BDS之链表
- 双链表:实现基本的增删查改,正反向现实双链表的节点
- OJ 系列之【中级】双链表基本操作
- 设计并实现一个LRU Cache
- 链表初解(二)——双链表的创建、删除、插入
- 数据结构之双向链表的Java实现
- 数据结构之双链表
- 线性表--双链表实现方式 (JAVA)
- 双链表基本操作
- C++实现的双链表通用模板