双向链表
来源:互联网 发布:js调用另一个js的函数 编辑:程序博客网 时间:2024/06/16 09:38
单链表的局限:
单链表的结点都只有一个指向下一个结点的指针。
单链表的数据元素无法直接访问其前驱元素。
逆序访问单链表中的元素是极其耗时的操作
双向链表的定义
在单链表的结点中增加一个指向其前驱的pre指针。
双向链表拥有单链表的所有操作
创建链表
销毁链表
获取链表长度
清空链表
获取第pos个元素操作
插入元素到位置pos
删除位置pos处的元素
插入操作
删除操作
双向链表的新操作
获取当前游标指向的数据元素
将游标重置指向链表中的第一个数据元素
将游标移动指向到链表中的下一个数据元素
将游标移动指向到链表中的上一个数据元素
直接指定删除链表中的某个数据元素
双向链表 的相关代码
//头文件 DLinkList.h#ifndef _DLINKLIST_H_#define _DLINKLIST_H_typedef void DLinkList;typedef struct _tag_DLinkListNode DLinkListNode;struct _tag_DLinkListNode{ DLinkListNode* next; DLinkListNode* pre; //新定义的前向指针 };struct Value //本结构体可以定义在main.c文件中,作为数据部分 { DLinkListNode header; int v;};DLinkList* DLinkList_Create();void DLinkList_Destroy(DLinkList* list);void DLinkList_Clear(DLinkList* list);int DLinkList_Length(DLinkList* list);int DLinkList_Insert(DLinkList* list, DLinkListNode* node, int pos);DLinkListNode* DLinkList_Get(DLinkList* list, int pos);DLinkListNode* DLinkList_Delete(DLinkList* list, int pos);DLinkListNode* DLinkList_DeleteNode(DLinkList* list, DLinkListNode* node);DLinkListNode* DLinkList_Reset(DLinkList* list);DLinkListNode* DLinkList_Current(DLinkList* list);DLinkListNode* DLinkList_Next(DLinkList* list);DLinkListNode* DLinkList_Pre(DLinkList* list);#endif
//双向链表 源文件 DLinkList.c#include <stdio.h>#include <malloc.h>#include "DLinkList.h"typedef struct _tag_DLinkList{ DLinkListNode header; DLinkListNode* slider; int length;} TDLinkList;DLinkList* DLinkList_Create() // O(1) 创建双向链表 { TDLinkList* ret = (TDLinkList*)malloc(sizeof(TDLinkList)); if( ret != NULL ) { ret->length = 0; ret->header.next = NULL; ret->header.pre = NULL; ret->slider = NULL; } return ret;}void DLinkList_Destroy(DLinkList* list) // O(1) 销毁双向链表 { free(list);}void DLinkList_Clear(DLinkList* list) // O(1) 清空双向链表 { TDLinkList* sList = (TDLinkList*)list; if( sList != NULL ) { sList->length = 0; sList->header.next = NULL; sList->header.pre = NULL; sList->slider = NULL; }}int DLinkList_Length(DLinkList* list) // O(1) 获取链表的数据长度 { TDLinkList* sList = (TDLinkList*)list; int ret = -1; if( sList != NULL ) { ret = sList->length; } return ret;}int DLinkList_Insert(DLinkList* list, DLinkListNode* node, int pos) // O(n)//插入某个元素 { TDLinkList* sList = (TDLinkList*)list; int ret = (sList != NULL) && (pos >= 0) && (node != NULL); int i = 0; if( ret ) { DLinkListNode* current = (DLinkListNode*)sList; DLinkListNode* next = NULL; for(i=0; (i<pos) && (current->next != NULL); i++) { current = current->next; } next = current->next; current->next = node; node->next = next; if( next != NULL ) { next->pre = node; } node->pre = current; if( sList->length == 0 ) { sList->slider = node; } if( current == (DLinkListNode*)sList ) { node->pre = NULL; } sList->length++; } return ret;}DLinkListNode* DLinkList_Get(DLinkList* list, int pos) // O(n) 获取某个元素 { TDLinkList* sList = (TDLinkList*)list; DLinkListNode* ret = NULL; int i = 0; if( (sList != NULL) && (0 <= pos) && (pos < sList->length) ) { DLinkListNode* current = (DLinkListNode*)sList; for(i=0; i<pos; i++) { current = current->next; } ret = current->next; } return ret;}DLinkListNode* DLinkList_Delete(DLinkList* list, int pos) // O(n) 删除某个元素 { TDLinkList* sList = (TDLinkList*)list; DLinkListNode* ret = NULL; int i = 0; if( (sList != NULL) && (0 <= pos) && (pos < sList->length) ) { DLinkListNode* current = (DLinkListNode*)sList; DLinkListNode* next = NULL; for(i=0; i<pos; i++) { current = current->next; } ret = current->next; next = ret->next; current->next = next; if( next != NULL ) { next->pre = current; if( current == (DLinkListNode*)sList ) { next->pre = NULL; } } if( sList->slider == ret ) { sList->slider = next; } sList->length--; } return ret;}DLinkListNode* DLinkList_DeleteNode(DLinkList* list, DLinkListNode* node){ TDLinkList* sList = (TDLinkList*)list; DLinkListNode* ret = NULL; int i = 0; if( sList != NULL ) { DLinkListNode* current = (DLinkListNode*)sList; for(i=0; i<sList->length; i++) { if( current->next == node ) { ret = current->next; break; } current = current->next; } if( ret != NULL ) { DLinkList_Delete(sList, i); } } return ret;}DLinkListNode* DLinkList_Reset(DLinkList* list){ TDLinkList* sList = (TDLinkList*)list; DLinkListNode* ret = NULL; if( sList != NULL ) { sList->slider = sList->header.next; ret = sList->slider; } return ret;}DLinkListNode* DLinkList_Current(DLinkList* list){ TDLinkList* sList = (TDLinkList*)list; DLinkListNode* ret = NULL; if( sList != NULL ) { ret = sList->slider; } return ret;}DLinkListNode* DLinkList_Next(DLinkList* list){ TDLinkList* sList = (TDLinkList*)list; DLinkListNode* ret = NULL; if( (sList != NULL) && (sList->slider != NULL) ) { ret = sList->slider; sList->slider = ret->next; } return ret;}DLinkListNode* DLinkList_Pre(DLinkList* list){ TDLinkList* sList = (TDLinkList*)list; DLinkListNode* ret = NULL; if( (sList != NULL) && (sList->slider != NULL) ) { ret = sList->slider; sList->slider = ret->pre; } return ret;}
小结
双向链表在单链表的基础上增加了指向前驱的指针。
功能上双向链表可以完全取代单链表的使用。
循环链表的Next,Pre和Current操作可以高效的遍历链表中的所有元素。
0 0
- SzNOI 双向约瑟夫(双向链表)
- 双向链表&&堆栈
- 双向链表
- 使用双向链表
- 双向链表
- 双向循环链表
- 双向循环链表
- 双向链表
- 实现双向链表
- 双向循环链表
- 建立双向链表
- 双向链表
- 双向链表
- 双向循环链表
- 双向链表
- 链表-双向链表
- 双向链表
- 双向动态链表
- bzoj 1706 倍增floyd
- Java内部类
- 【问底】徐汉彬:亿级Web系统搭建——单机到分布式集群
- JBPM工作流引擎之并发流程&组任务&事件&自定义任务
- NODEMCU刷入AT固件后
- 双向链表
- 自定义拦截器
- 服务器配置git
- 关于Form表单提交中文乱码问题
- 第十章:Java_IO流
- enginx之于分布式部署的创新意义:服务器的服务器,通用分布式服务器引擎,集群引擎-使任何服务器程序纳入统一生态
- Can’t connect to local MySQL server through socket 解决办法
- (45). Spring Boot MyBatis连接Mysql数据库【从零开始学Spring Boot】
- SparkMlib实现线性回归