赞
踩
目录
要实现带头的双向循环链表,我们需要知道什么是头节点,如何循环。
首先,头节点是一个不存任何数据的节点,链表为空,也就是指此链表只有一个头节点。
其次,循环,则是指头指向尾,尾指向头,当链表尾空时,其头节点既是表头,也是表尾。
最后,双向,则是指其可以向前访问,也可以向后访问,这也说明了双向链表是由两个指针的,一个指向头,一个指向尾。
接下来我们定义一个双向循环链表,为了更方便的表示,我们对其进行再次封装
- #include <stdlib.h>
- #include <stdio.h>
-
- typedef int LNElemType;
- typedef struct ListNode{
- LNElemType val;
- struct ListNode* prev;
- struct ListNode* next;
- }ListNode;
-
- typedef struct BidList{
- ListNode* head;
- size_t size;
- }BidList;
考虑到数据的类型时不固定的,所以我们给出函数指针,对于不同的数据类型,由用户进行处理,我们只对基础数据类型进行处理
- typedef void(*PRINT)(LNElemType* val);
- typedef bool(*COMPARE)(LNElemType* src, LNElemType* des);
- typedef void(*ASSIG)(LNElemType* src, LNElemType* des);
-
- void printChar(char* val){
- printf("%c", *val);
- }
-
- void printShort(short* val){
- printf("%h", *val);
- }
-
- void printInt(int* val){
- printf("%d", *val);
- }
-
- void printLong(long* val){
- printf("%ld", *val);
- }
-
- void printfLongLong(long long* val){
- printf("%lld", *val);
- }
-
- void printFloat(float* val){
- printf("%f", *val);
- }
-
- void printDouble(double* val){
- printf("%lf", *val);
- }
-
- void printString(char** val){
- printf("%s", *val);
- }
- void IsEqual(LNElemType* src, LNElemType* des){
- return *src == *des;
- }
-
- void MoreThan(LNElemType* src, LNElemType* des){
- return *src < *des;
- }
-
- void LessThan(LNElemType* src, LNElemType* des){
- return *src > *des;
- }
-
- void setValue(LNElemType* src, LNElemType* des){
- *src = *des;
- }
- void BidListInit(BidList* phead)
- {
- assert(phead != NULL);
- phead->head = (ListNode*)malloc(sizeof(ListNode));
- if (phead->head == NULL)
- {
- perror("Init fail");
- exit(1);
- }
- phead->head->next = phead->head;
- phead->head->prev = phead->head;
- //考虑到链表的初始数据可能会是一个结构,所以我们不为头节点赋初始值,防止发生错误
- }
- ListNode* BuyNode(){
- ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
- assert(newNode);
- return newNode;
- }
- void BidListPushFront(BidList* phead, LNElemType val, ASSIG setValue){
- assert(phead != NULL);
- //创建节点
- ListNode* newNode = BuyNode();
- setValue(&newNode->val, &val);
- ListNode* first = phead->head->next;
- first->prev = newNode;
- newNode->next = first;
- newNode->prev = phead->head;
- phead->head->next = newNode;
- phead->size++;
- }
- void BidListPushBack(BidList* phead, LNElemType val, ASSIG setValue){
- assert(phead != NULL);
- ListNode* newNode = BuyNode();
- setValue(&newNode->val, &val);
- ListNode* tail = phead->head->prev;
- tail->next = newNode;
- newNode->next = phead->head;
- newNode->prev = tail;
- phead->head->prev = newNode;
- phead->size++;
- }
- void BidListInert(BidList* phead, ListNode* pos, LNElemType val, ASSIG setValue){
- assert(pos != NULL);
- assert(phead != NULL);
- ListNode* newNode = BuyNode();
- setValue(&newNode->val, &val);
- ListNode* cur = pos->prev;
- cur->next = newNode;
- newNode->prev = cur;
- newNode->next = pos;
- pos->prev = newNode;
- phead->size++;
- }
- void BidListPopFront(BidList* phead){
- assert(phead != NULL);
- if (phead->size == 0)
- {
- return;
- }
- ListNode* head = phead->head->next;
- phead->head->next = head->next;
- head->next->prev = phead->head;
- free(head);
- phead->size--;
- }
- void BidListPopBack(BidList* phead){
- assert(phead != NULL);
- if (phead->size == 0)
- {
- return;
- }
- ListNode* tail = phead->head->prev;
- tail->prev->next = phead->head;
- phead->head->next = tail->prev;
- free(tail);
- phead->size--;
- }
- void BidListErase(BidList* phead, ListNode* pos){
- assert(pos != NULL);
- assert(phead != NULL);
- ListNode* next = pos->next;
- ListNode* prev = pos->prev;
- next->prev = prev;
- prev->next = next;
- free(pos);
- phead->size--;
- }
- void BidListModify(BidList* phead, LNElemType src, LNElemType des, COMPARE IsEqual, ASSIG setValue){
- assert(phead != NULL);
- ListNode* p = phead->head->next;
- while (p != phead->head){
- if (IsEqual(&p->val, &src))
- {
- setValue(&p->val, &des);
- break;
- }
- p = p->next;
- }
- }
- ListNode* BidListFind(BidList* phead, LNElemType val, COMPARE IsEqual){
- assert(phead);
- ListNode* p = phead->head->next;
- while (p != phead->head){
- if (IsEqual(&p->val, &val)){
- return p;
- }
- p = p->next;
- }
- return NULL;
- }
- void BidListPrint(BidList* phead, PRINT print){
- assert(phead);
- ListNode* head = phead->head->next;
- printf("guard<->");
- while (head != phead->head){
- print(&head->val);
- printf("<->");
- head = head->next;
- }
- printf("guard\n");
- }
- void BidListDestory(BidList* phead){
- assert(phead != NULL);
- ListNode* p = phead->head->next;
- ListNode* t = p;
- while (p->next != phead->head){
- p = t->next;
- free(t);
- t = p;
- }
- free(phead->head);
- phead->head = NULL;
- phead->size = 0;
- }
- void BidListClear(BidList* phead){
- assert(phead != NULL);
- ListNode* p = phead->head->next;
- ListNode* t = p;
- while (p->next != phead->head){
- p = t->next;
- free(t);
- t = p;
- }
- phead->head->next = phead->head;
- phead->head->prev = phead->head;
- phead->size = 0;
- }
- bool BidListIsEmpty(BidList* phead)
- {
- assert(phead != NULL);
- return phead->size == 0;
- }
-
- void test01()
- {
- BidList list;
- BidListInit(&list);
- BidListPushBack(&list, 1, setValue);
- BidListPushBack(&list, 2, setValue);
- BidListPushBack(&list, 3, setValue);
- BidListPushFront(&list, 10, setValue);
- BidListPushFront(&list, 20, setValue);
- BidListPushFront(&list, 30, setValue);
-
- BidListPrint(&list, printInt);
-
- ListNode* pos = BidListFind(&list, 2, IsEqual);
-
- BidListInert(&list, pos, 200, setValue);
- BidListErase(&list, pos);
-
- BidListModify(&list, 200, 100, IsEqual, setValue);
-
- BidListPrint(&list, printInt);
-
- BidListClear(&list);
-
- BidListPrint(&list,printInt);
-
-
-
- BidListPopBack(&list);
-
-
- BidListDestory(&list);
- }
-
-
- int main()
- {
-
- test01();
- system("pause");
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。