第11课-双向链表

1. 单链表的局限

(1)      单链表的结点都只有一个指向下一个结点的指针。

(2)      单链表的数据元素无法直接访问其前驱元素。

l  逆序访问单链表中的元素是极其耗时的操作!

len = LinkList_Length(list);

for(i=len-1; len>=0; i--)

{

LinkListNode* p = LinkList_Get(list,i);

//访问数据元素p中的元素

}

2. 双向链表的定义

在单链表的结点中增加一个指向其前驱的pre指针。

3. 双向链表拥有单链表的所有操作

(1)      创建链表。

(2)      销毁链表。

(3)      获取链表长度。

(4)      清空链表。

(5)      获取第pos个元素操作。

(6)      插入元素到位置pos。

(7)      删除位置p。

4. 双向链表的插入操作

current->next = node;

node->next =next;

next->pre = node;

node->pre = current;

5. 双向链表的删除操作

current->next = next;

next-> = current;

6. 双向链表的新操作

(1)      获取当前游标指向的数据元素。

(2)      将游标重置指向链表中的第一个数据元素。

(3)      将游标移动指向到链表中的下一个数据元素。

(4)      将游标移动指向到链表中的上一个数据元素。

(5)      直接指定删除链表中的某个数据元素。

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);

DLinkList.h

#ifndef _DLINKLIST_H_

#define _DLINKLIST_H_

typedef void DLinkList;

typedef struct _tag_DLinkListNode DLinkListNode;

struct _tag_DLinkListNode

{

DLinkListNode* next;

DLinkListNode* pre;

};

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 )

{

node->pre = NULL;

sList->slider = node;

}

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;

}

main.c

#include <stdio.h>

#include <stdlib.h>

#include "DLinkList.h"

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

struct Value

{

DLinkListNode header;

int v;

};

int main(int argc, char *argv[])

{

int i = 0;

DLinkList* list = DLinkList_Create();

struct Value* pv = NULL;

struct Value v1;

struct Value v2;

struct Value v3;

struct Value v4;

struct Value v5;

v1.v = 1;

v2.v = 2;

v3.v = 3;

v4.v = 4;

v5.v = 5;

DLinkList_Insert(list, (DLinkListNode*)&v1, DLinkList_Length(list));

DLinkList_Insert(list, (DLinkListNode*)&v2, DLinkList_Length(list));

DLinkList_Insert(list, (DLinkListNode*)&v3, DLinkList_Length(list));

DLinkList_Insert(list, (DLinkListNode*)&v4, DLinkList_Length(list));

DLinkList_Insert(list, (DLinkListNode*)&v5, DLinkList_Length(list));

for(i=0; i<DLinkList_Length(list); i++)

{

pv = (struct Value*)DLinkList_Get(list, i);

printf("%d\n", pv->v);

}

printf("\n");

DLinkList_Delete(list, DLinkList_Length(list)-1);

DLinkList_Delete(list, 0);

for(i=0; i<DLinkList_Length(list); i++)

{

pv = (struct Value*)DLinkList_Next(list);

printf("%d\n", pv->v);

}

printf("\n");

DLinkList_Reset(list);

DLinkList_Next(list);

pv = (struct Value*)DLinkList_Current(list);

printf("%d\n", pv->v);

DLinkList_DeleteNode(list, (DLinkListNode*)pv);

pv = (struct Value*)DLinkList_Current(list);

printf("%d\n", pv->v);

DLinkList_Pre(list);

pv = (struct Value*)DLinkList_Current(list);

printf("%d\n", pv->v);

printf("Length: %d\n", DLinkList_Length(list));

DLinkList_Destroy(list);

return 0;

}

小结

l  双向链表在单链表的基础上增加了指向前驱的指针。

l  功能上双向链表可以完全取代单链表的使用。

l  循环链表的Next,Pre和Current操作可以高效的。

l  遍历链表中的所有元素。

转载于:https://www.cnblogs.com/free-1122/p/11322751.html

数据-第11课-双向链表相关推荐

  1. Spark商业案例与性能调优实战100课》第11课:商业案例之通过纯粹通过DataFrame分析大数据电影点评系仿QQ和微信、淘宝等用户群分析与实战

    Spark商业案例与性能调优实战100课>第11课:商业案例之通过纯粹通过DataFrame分析大数据电影点评系仿QQ和微信.淘宝等用户群分析与实战

  2. 调试断点_接口测试第11课(断点调试)

    同学们,大家好,今天我们开始学习11课了,这节我们讲断点调试. 一. 使用Fiddler进行HTTP断点调试. 这是Fiddler又一强大和实用的工具之一.通过设置断点,Fiddler可以做到: 1. ...

  3. 当且仅当函数依赖a→b在r上成立_数据库第06章关系数据理习题课.ppt

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp计算机&nbsp>&nbsp数据结构与算法 数据库第06章关系数据理习题课.ppt36页 本 ...

  4. ArchieOpenGL教程第11课:使用位图字体 在屏幕上显示字体

    第十一课A 源代码 图像字体A: 这一课我们将创建一些基于2D图像的字体,它们可以缩放,但不能旋转,并且总是面向前方,但作为基本的显示来说,我想已经够了. 使用位图字体比起使用图形字体(贴图)看起来不 ...

  5. python逐笔输入数据_知到智慧树Python数据分析与数据可视化结课测验

    知到智慧树Python数据分析与数据可视化结课测验答案 更多相关问题 已知三角形三个顶点的坐标是A(-1,2,3),B(1,1,1),C(0,0,5),试证三角形ABC是直角三角形,并求角B-- Wh ...

  6. 视频教程-大数据分析师实战课-大数据

    大数据分析师实战课 任老师,Cloudera管理/开发/分析认证讲师,华为高级特聘讲师,新华三大学高级特聘讲师,中国大数据技术与应用联盟高级讲师,全国高校大数据联盟特聘讲师,中国移动高级讲师,前IBM ...

  7. linux下enum类型占几个字节,第11课 - enum, sizeof, typedef 分析

    第11课 - enum, sizeof, typedef 分析 1. enum介绍 (1)enum是C语言中的一种自定义类型,和struct.union地位相同,格式如下: // enum每个值的最后 ...

  8. 《实用C++》第11课:if 语句实现逻辑运算与冒号表达式

    本文转载自:VC驿站 https://www.cctry.com/thread-279233-1-1.html 1.逻辑运算概述: 为什么会有逻辑运算呢?举个例子,上节课的一段小代码: int zha ...

  9. 「缠师课后回复精选」第11课:不会吻,无以高潮!

    教你炒股票11:不会吻,无以高潮! 2006-11-29 12:00:00 本课精读详解参阅:「狩猎精读缠论」第11课 不会吻,无以高潮! 甄别"早泄"男,必须要选择三个独立的系统 ...

  10. 大数据入门第一课 Hadoop基础知识与电商网站日志数据分析

    大数据入门第一课 Hadoop基础知识与电商网站日志数据分析 本课程从Hadoop核心技术入手,以电商项目为依托,带领你从0基础开始上手,逐步掌握大数据核心技术(如:HDFS.YARN.MapRedu ...

最新文章

  1. 我的Android进阶之旅------Android嵌入图像InsetDrawable的用法
  2. 干货 | 详解对象检测模型中的Anchors
  3. PL/SQL数据库字符集问题
  4. Intel Realsense 处理帧时报错:RuntimeError: null pointer passed for argument frame_ref
  5. ubuntu java classpath_java – 如何为Ubuntu中的文件夹设置CLASSPATH变量
  6. HDU 2047 阿牛的EOF牛肉串
  7. python编辑器对比和推荐
  8. P3309-[SDOI2014]向量集【线段树,凸壳】
  9. [笔记]VI编辑器的学习
  10. xp 系统 mysql日志文件在哪里_SqlServer修改数据库文件及日志文件存放位置教程
  11. 让注册体验来得更简单点吧
  12. Python3爬虫与多线程
  13. asp.net 与donet(.net)的区别
  14. 用FFmpeg快捷加文字水印
  15. 关于.length与.length()的问题
  16. 【Python代码实践】使用Python批量获取雨课堂图片
  17. 我提交了一个 pr,只是为了吃
  18. JTAG和SWD定义
  19. 布法罗大学计算机硕士学费,纽约布法罗大学学费是多少
  20. 创建RAID5磁盘阵列和RAID10磁盘阵列

热门文章

  1. Flutter实战之Dio入门使用
  2. mongodb分页优化
  3. 嵌入式linux系统运行程序,嵌入式Linux系统启动过程
  4. html 边框轮廓,CSS Outline(轮廓)
  5. kali linux 自动登录,Kali Linux SSH登录故障处理
  6. golang下载网站的实例的办法
  7. H3C交换机设备使用QOS策略方式实现报文过滤
  8. 帆软决策报表JS实现点击超链切换TAB页
  9. mysql 两条数据相减_mysql 实现相邻两条数据相减
  10. bim服务器型号,国外有哪几个知名的BIM服务器?BIM服务器全介绍!(三)