双向链表的简单操作
2018-04-08 20:37
393 查看
以下是有关双向链表的一些简单操作,例如增删查改。
link.h
#pragma once #include <stdio.h> #define TITLE printf("\n========================%s======================\n",__FUNCTION__); typedef char DLinkType; typedef struct DLinkNode { DLinkType data; struct DLinkNode* next; struct DLinkNode* prev; }DLinkNode; DLinkNode* CreateNode(DLinkType value); //创建结点 void DestroyNode(DLinkNode** to_delete);//销毁结点 void DLinkListInit(DLinkNode** head); //初始化 void DLinkListPrint(DLinkNode* head,const char *msg); //链表打印 void DLinkListPushBack(DLinkNode* head, DLinkType value);//尾插一个元素 void DLinkListPopBack(DLinkNode* head);//尾删 void DLinkListPushFront(DLinkNode* head, DLinkType value);//头插一个元素 void DLinkListPopFront(DLinkNode* head);//头删 DLinkNode* DLinkListFind(DLinkNode* head, DLinkType to_find);//查找元素 void DLinkListInsert(DLinkNode*head,DLinkNode* pos, DLinkType value);//指定位置前插入一个元素 void DLinkListInsertAfter(DLinkNode*head,DLinkNode* pos, DLinkType value);//指定位置后插入一个元素 void DLinkListErase(DLinkNode* head,DLinkNode* pos);//删除结点pos void DLinkListRemove(DLinkNode* head,DLinkType value);//删除指定元素结点 void DLinkListRemoveAll(DLinkNode* head,DLinkType value);//删除指定元素所有结点 size_t DLinkListSize(DLinkNode* head);//返回链表结点数 int DLinkListEmpty(DLinkNode* head);//判断链表是否为空,链表为空返回0,链表不为空返回1
link.c
#include "link.h" #include <stdlib.h> #include <stddef.h> DLinkNode* CreateNode(DLinkType value) { DLinkNode* new_node = (DLinkNode*)malloc(sizeof(DLinkNode)); new_node->data = value; new_node->next = new_node; new_node->prev = new_node; return new_node; } void DestroyNode(DLinkNode** to_delete) { free(*to_delete); } void DLinkListPrint(DLinkNode* head,const char* msg) { printf("[%s]:\n",msg); if(head == NULL) { return; } DLinkNode* cur = head->next; while(cur != head) { printf("[%c|%p] ",cur->data,cur); cur = cur->next; } printf("\n"); cur = head->prev; while(cur != head) { printf("[%c|%p] ",cur->data,cur); cur = cur->prev; } printf("\n"); } void DLinkListInit(DLinkNode** head) { if(head == NULL) { //非法输入 return; } *head = CreateNode(0); } void DLinkListPushBack(DLinkNode* head, DLinkType value) { if(head == NULL) { //非法输入 return; } DLinkNode* tail = head->prev; DLinkNode* new_node = CreateNode(value); //tail vs new_node tail->next = new_node; new_node->prev = tail; //head vs new_node new_node->next = head; head->prev = new_node; return; } void DLinkListPopBack(DLinkNode* head) { if(head == NULL) { //非法输入 return; } if(head->next == head) { DestroyNode(&head); return; } DLinkNode* tail = head->prev; DLinkNode* Prev = tail->prev; //Prev vs head Prev->next = head; head->prev = Prev; } void DLinkListPushFront(DLinkNode* head, DLinkType value) { if(head == NULL) { return; } DLinkNode* new_node = CreateNode(value); DLinkNode* Prev = head->next; //new_node vs Prev new_node->next = Prev; Prev->prev = new_node; //new_node vs head head->next = new_node; new_node->prev = head; return; } void DLinkListPopFront(DLinkNode* head) { if(head == NULL) { return; } if(head->next == head) { DestroyNode(&head); return; } DLinkNode* to_delete = head->next; DLinkNode* next = to_delete->next; head->next = next; next->prev = head; DestroyNode(&to_delete); return; } DLinkNode* DLinkListFind(DLinkNode* head, DLinkType to_find) { if(head == NULL) { return NULL; } DLinkNode* cur = head->next; while(cur != head) { if(cur->data == to_find) return cur; cur = cur->next; } return NULL; } void DLinkListInsert(DLinkNode*head,DLinkNode* pos, DLinkType value) { if(head == NULL) { return; } if(pos == NULL) { return; } DLinkNode* new_node = CreateNode(value); DLinkNode* pos_prev = pos->prev; //new_node vs pos_prev pos_prev->next = new_node; new_node->prev = pos_prev; //new_node vs pos new_node->next = pos; pos->prev = new_node; } void DLinkListInsertAfter(DLinkNode*head,DLinkNode* pos, DLinkType value) { if(head == NULL) { return; } if(pos == NULL) { return; } DLinkNode* new_node = CreateNode(value); DLinkNode* pos_next = pos->next; //new_node vs pos pos->next = new_node; new_node->prev = pos; //new_node vs pos->next new_node->next = pos_next; pos_next->prev = new_node; } void DLinkListErase(DLinkNode* head,DLinkNode* pos) { if(head == NULL) { return; } if(pos == NULL) { return; } DLinkNode* next = pos->next; DLinkNode* prev = pos->prev; //prev vs next prev->next = next; next->prev = prev; DestroyNode(&pos); return; } void DLinkListRemove(DLinkNode* head,DLinkType value) { if(head == NULL) { return; } DLinkNode* cur = head->next; while(cur != head) { if(cur->data == value) { DLinkNode* prev = cur->prev; DLinkNode* next = cur->next; prev->next = next; next->prev = prev; DestroyNode(&cur); return; } cur = cur->next; } return; } void DLinkListRemoveAll(DLinkNode* head,DLinkType value) { if(head == NULL) { return; } DLinkNode* cur = head->next; while(cur != head) { if(cur->data == value) { DLinkNode* prev = cur->prev; DLinkNode* next = cur->next; prev->next = next; next->prev = prev; DLinkNode* to_delete = cur; DestroyNode(&to_delete); cur = prev; } cur = cur->next; } } size_t DLinkListSize(DLinkNode* head) { if(head == NULL) { return 0; } size_t count = 0; DLinkNode* cur = head->next; while(cur != head) { count++; cur = cur->next; } return count; } int DLinkListEmpty(DLinkNode* head) { if(head == NULL) { return 0; } if(head->next == head && head->prev == head) { return 0; } else { return 1; } } //////////////////////////////////////////////////////////////////////////////// // 以下为测试代码 // //////////////////////////////////////////////////////////////////////////////// void TestInit() { TITLE; DLinkNode* head; DLinkListInit(&head); DLinkListPrint(head,"打印空链表"); } void TestDLinkListPushBack() { TITLE; DLinkNode* head; DLinkListInit(&head); DLinkListPushBack(head,'a'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'c'); DLinkListPushBack(head,'d'); DLinkListPrint(head,"尾插4个元素"); } void TestDLinkListPopBack() { TITLE; DLinkNode* head; DLinkListInit(&head); DLinkListPushBack(head,'a'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'c'); DLinkListPushBack(head,'d'); DLinkListPrint(head,"尾插4个元素"); DLinkListPopBack(head); DLinkListPopBack(head); DLinkListPrint(head,"尾删2个元素"); DLinkListPopBack(head); DLinkListPopBack(head); DLinkListPrint(head,"再尾删2个元素"); DLinkListPrint(head,"对空链表进行尾删"); } void TestDLinkListPushFront() { TITLE; DLinkNode* head; DLinkListInit(&head); DLinkListPushFront(head,'a'); DLinkListPushFront(head,'b'); DLinkListPushFront(head,'c'); DLinkListPushFront(head,'d'); DLinkListPrint(head,"头插4个元素"); } void TestDLinkListPopFront() { TITLE; DLinkNode* head; DLinkListInit(&head); DLinkListPushFront(head,'a'); DLinkListPushFront(head,'b'); DLinkListPushFront(head,'c'); DLinkListPushFront(head,'d'); DLinkListPrint(head,"头插4个元素"); DLinkListPopFront(head); DLinkListPopFront(head); DLinkListPrint(head,"头删2个元素"); DLinkListPopFront(head); DLinkListPopFront(head); DLinkListPrint(head,"再头删2个元素"); DLinkListPrint(head,"头删空链表"); } void TestDLinkListFind() { TITLE; DLinkNode* head; DLinkListInit(&head); DLinkListPushBack(head,'a'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'c'); DLinkListPushBack(head,'d'); DLinkListPrint(head,"尾插4个元素"); DLinkNode* find = DLinkListFind(head,'x'); printf("[查找元素x]:%p\n",find); find = DLinkListFind(head,'c'); printf("[查找元素c]:%p\n",find); } void TestDLinkListInsert() { TITLE; DLinkNode* head; DLinkListInit(&head); DLinkListPushBack(head,'a'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'c'); DLinkListPushBack(head,'d'); DLinkListPrint(head,"尾插4个元素"); DLinkNode* pos_a = DLinkListFind(head,'a'); DLinkListInsert(head,pos_a,'x'); DLinkList ab36 Print(head,"元素a之前插入x"); DLinkNode* pos_c = DLinkListFind(head,'c'); DLinkListInsert(head,pos_c,'h'); DLinkListPrint(head,"元素c之前插入h"); } void TestDLinkListInsertAfter() { TITLE DLinkNode* head; DLinkListInit(&head); DLinkListPushBack(head,'a'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'c'); DLinkListPushBack(head,'d'); DLinkListPrint(head,"尾插4个元素"); DLinkNode* pos_a = DLinkListFind(head,'a'); DLinkListInsertAfter(head,pos_a,'x'); DLinkListPrint(head,"元素a之后插入x"); DLinkNode* pos_d = DLinkListFind(head,'d'); DLinkListInsertAfter(head,pos_d,'h'); DLinkListPrint(head,"元素d之后插入h"); } void TestDLinkListErase() { TITLE DLinkNode* head; DLinkListInit(&head); DLinkListPushBack(head,'a'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'c'); DLinkListPushBack(head,'d'); DLinkListPrint(head,"尾插4个元素"); DLinkNode* pos_b = DLinkListFind(head,'b'); DLinkListErase(head,pos_b); DLinkListPrint(head,"删除结点b"); } void TestDLinkListRemove() { TITLE DLinkNode* head; DLinkListInit(&head); DLinkListPushBack(head,'a'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'c'); DLinkListPushBack(head,'d'); DLinkListPrint(head,"尾插4个元素"); DLinkListRemove(head,'b'); DLinkListPrint(head,"删除元素b结点"); } void TestDLinkListRemoveAll() { TITLE DLinkNode* head; DLinkListInit(&head); DLinkListPushBack(head,'a'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'c'); DLinkListPushBack(head,'d'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'b'); DLinkListPrint(head,"尾插4个元素"); DLinkListRemoveAll(head,'b'); DLinkListPrint(head,"删除所有元素b结点"); } void TestDLinkListSize() { TITLE DLinkNode* head; DLinkListInit(&head); DLinkListPushBack(head,'a'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'c'); DLinkListPushBack(head,'d'); DLinkListPrint(head,"尾插4个元素"); int t = DLinkListSize(head); printf("[链表长度为]:\nexpect is 4,actul is %d\n",t); } void TestDLinkListEmpty() { TITLE DLinkNode* head; DLinkListInit(&head); int t = DLinkListEmpty(head); printf("[链表是否为空]:\nexpect is 0,actul is %d\n",t); DLinkListPushBack(head,'a'); DLinkListPushBack(head,'b'); DLinkListPushBack(head,'c'); DLinkListPushBack(head,'d'); DLinkListPrint(head,"尾插4个元素"); t = DLinkListEmpty(head); printf("[链表是否为空]:\nexpect is 1,actul is %d\n",t); } int main() { TestInit(); TestDLinkListPushBack(); TestDLinkListPopBack(); TestDLinkListPushFront(); TestDLinkListPopFront(); TestDLinkListFind(); TestDLinkListInsert(); TestDLinkListInsertAfter(); TestDLinkListErase(); TestDLinkListRemove(); TestDLinkListRemoveAll(); TestDLinkListSize(); TestDLinkListEmpty(); return 0; }
以下为程序运行结果:
相关文章推荐
- (C++版)链表(四)——实现双向循环链表创建、插入、删除等简单操作
- c语言 之 双向链表 简单操作
- (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作
- 双向链表的简单操作
- 双向链表的简单操作
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
- 详谈双向链表的实现与简单操作
- C++ 双向链表的简单操作
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
- (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作
- (C++版)链表(三)——实现双向链表的创建、插入、删除等简单操作
- BNUOJ 26182 -----------Army Buddies 用结构体 仿双向链表的简单操作
- 双向链表简单操作
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
- (C++版)链表(四)——实现双向循环链表创建、插入、删除等简单操作
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
- (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作
- 双向链表的简单操作
- 算法(05):基本链表的操作及双向链表
- 双向链表的一些操作