线性表->链式存储->双向链表
文字描述
之前的链表(单链表、循环链表)的链式存储结构中只有一个指示直接后继的指针域。由此,从某个结点出发只能顺指针往后寻查其他结点。若要寻查结点的直接前驱,则需从表头指针出发。即单链表中,NextElem的执行时间为1,而PriorElem的执行时间为n。为了克服单链表这种缺点,可利用双向链表。
在双向链表中,每个节点有两个指针域,一个指向其直接后继,一个指向其直接前驱。
示意图

算法分析
插入、删除、查找、求后继等同单链表。但是求前驱不一样,其时间复杂度为1。
代码实现
//
// Created by lady on 19-1-31.
// #include <stdlib.h>
#include <stdio.h>
#include <string.h> //线性表的双向循环链表存储结构
typedef struct ElemType{
char data[];
}ElemType;
typedef struct DuLNode{
ElemType e;
struct DuLNode *prior;
struct DuLNode *next;
}DuLNode, *DuLinkList; //构造一个空的双向循环链表
static int InitList_DuL(DuLinkList *L)
{
(*L) = (DuLinkList)malloc(sizeof(DuLNode));
(*L)->prior = (*L);
(*L)->next = (*L);
memset((*L)->e.data, , sizeof((*L)->e.data));
return ;
} //销毁L
static int Destory_DuL(DuLinkList *L)
{
DuLNode *p = NULL;
DuLNode *q = NULL;
p = (*L)->next;
while(p){
q = p;
p = p->next;
free(q);
if(p == (*L))
break;
}
free(*L);
(*L) = NULL;
return ;
} //返回双向链表L中的第i个位置的元素
static DuLNode *GetElemP_DuL(DuLinkList *L, int i)
{
if(L == NULL){
return NULL;
}
DuLNode *p = (*L)->next;
int index = ;
while(index<i && p){
index += ;
p = p->next;
}
if(index == i && p){
return p;
}else{
return NULL;
}
} //在L的指定位置i的元素前面插入元素e
static int ListInsert_DuL(DuLinkList *L, int i, ElemType e)
{
DuLNode *p = NULL;
DuLNode *new = NULL;
if((p=GetElemP_DuL(L, i)) == NULL){
return -;
}
if((new = (DuLNode*)malloc(sizeof(DuLNode))) == NULL){
return -;
}
new->e = e;
new->prior = p->prior;
p->prior->next = new;
new->next = p;
p->prior = new;
return ;
} //删除L中的第loc个数据元素,并将被删元素的值存放在e中
static int ListDelete_DuL(DuLinkList *L, int i, ElemType *e)
{
DuLNode *p = NULL;
if((p=GetElemP_DuL(L, i)) == NULL){
return -;
}
(*e) = p->e;
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
return ;
} //依次对L的每个数据元素调用函数fun
static int listTraverse_DuL(DuLinkList *L, int (*fun)(ElemType,int), char note[])
{
printf("遍历双向循环链表%s:", note);
DuLNode *p = NULL;
p = (*L)->next;
int i = ;
while(p){
fun(p->e, i);
i+=;
p = p->next;
if(p == (*L))
break;
}
printf("\n");
return ;
} static int print(ElemType e, int loc)
{
printf("%3d=%-10s", loc, e.data);
} //创建一个长度为n的双向链表
static int CreateList_DuL(DuLinkList *L, int n, char note[])
{
printf("创建一个长度为%d的双向循环链表%s!\n", n, note);
InitList_DuL(L);
ElemType e;
int i = ;
for(i=; i<n; i++){
printf("输入第%d个元素:", i+);
scanf("%s[^\\n]", e.data);
ListInsert_DuL(L, i+, e);
}
return ;
} int main(int argc, char *argv[])
{
ElemType e;
DuLinkList L;
int location=; CreateList_DuL(&L, , "L"); listTraverse_DuL(&L, print, "L"); printf("输入插入元素的位置:");
scanf("%d", &location);
printf("输入插入元素的数据:");
scanf("%s[^\\n]", e.data);
ListInsert_DuL(&L, location, e);
listTraverse_DuL(&L, print, "L"); printf("输入删除元素的位置:");
scanf("%d", &location);
ListDelete_DuL(&L, location, &e); printf("位于%d的元素%s已经从双向循环链表中被删除!\n", location, e.data);
listTraverse_DuL(&L, print, "L"); Destory_DuL(&L);
printf("双向链表已经被销毁!\n");
return ;
}
双向链表
代码运行
/home/lady/CLionProjects/untitled/cmake-build-debug/untitled
创建一个长度为5的双向循环链表L!
输入第1个元素:c
输入第2个元素:b
输入第3个元素:e
输入第4个元素:g
输入第5个元素:f
遍历双向循环链表L: 1=c 2=b 3=e 4=g 5=f
输入插入元素的位置:3
输入插入元素的数据:test
遍历双向循环链表L: 1=c 2=b 3=test 4=e 5=g 6=f
输入删除元素的位置:4
位于4的元素e已经从双向循环链表中被删除!
遍历双向循环链表L: 1=c 2=b 3=test 4=g 5=f
双向链表已经被销毁! Process finished with exit code 0
线性表->链式存储->双向链表的更多相关文章
- 线性表->链式存储->循环链表
文字描述 循环链表是另一种形式的链式存储结构.它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环.由此,从表中任一结点出发均可找到表中其他结点. 示意图 算法分析 插入.删除.查找等同单 ...
- 线性表->链式存储->线形链表(单链表)
文字描述: 为了表示前后两个数据元素的逻辑关系,对于每个数据元素,除了存储其本身的信息之外(数据域),还需存储一个指示其直接后继的信息(即直接后继的存储位置,指针域). 示意图: 算法分析: 在单链表 ...
- C语言实现线性表(链式存储方式)
#include <stdio.h> #include <stdlib.h> //提供malloc()原型 typedef struct LNode *List; typede ...
- C语言 线性表 链式表结构 实现
一个单链式实现的线性表 mList (GCC编译). /** * @brief 线性表的链式实现 (单链表) * @author wid * @date 2013-10-21 * * @note 若代 ...
- javascript实现数据结构:线性表--线性链表(链式存储结构)
上一节中, 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单,直观的公式来表示.然后,另一方面来看,这个特点也造成这种存储 ...
- 算法与数据结构(一) 线性表的顺序存储与链式存储(Swift版)
温故而知新,在接下来的几篇博客中,将会系统的对数据结构的相关内容进行回顾并总结.数据结构乃编程的基础呢,还是要不时拿出来翻一翻回顾一下.当然数据结构相关博客中我们以Swift语言来实现.因为Swift ...
- c数据结构 -- 线性表之 复杂的链式存储结构
复杂的链式存储结构 循环链表 定义:是一种头尾相接的链表(即表中最后一个结点的指针域指向头结点,整个链表形成一个环) 优点:从表中任一节点出发均可找到表中其他结点 注意:涉及遍历操作时,终止条件是判断 ...
- [置顶] ※数据结构※→☆线性表结构(queue)☆============优先队列 链式存储结构(queue priority list)(十二)
优先队列(priority queue) 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除.在优先队列中,元素被赋予优先级.当访问元素时,具有最高优先级的元素最先删除.优先队列具有 ...
- C++编程练习(2)----“实现简单的线性表的链式存储结构“
单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素. 对于查找操作,单链表的时间复杂度为O(n). 对于插入和删除操作,单链表在确定位置后,插入和删除时间仅为O(1). 单链表不需要分配存储 ...
随机推荐
- 10张思维导图带你学习JavaScript
10张思维导图带你学习JavaScript 下面将po出10张JavaScript相关的思维导图. 分别归类为: JavaScript变量 JavaScript运算符 JavaScript数组 ...
- 解决nginx和php使用ckfinder无法上传大文件的问题
现象描述:cms内容发布系统上传不了大文件,当上传超过32M文件时就上传不了 提示:无效的文件. 文件尺寸太大. 分析文件上传过程:browser --> nginx --> php 需要 ...
- JS 对Array集合排序的方法
我的业务是根据距离的远近经行一个排序: 第一种方法:冒泡排序 排序前的数据是这样子的: 排序后是这样子的: 代码可以直接复制使用的: <!doctype html> <html> ...
- SpringBoot 集成数据库连接池Druid
1.pom.xml依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>druid< ...
- Excel 恢复默认行高、列宽
操作系统:Windows 10 x64 工具1:Excel 乱糟糟的! 选中需要调整的区域,选择菜单:开始 > 格式 > 自动调整行高 选中需要调整的区域,选择菜单:开始 > 格式 ...
- c/c++/java如何访问数据库(优秀博文)
(下面是c++) https://www.cnblogs.com/47088845/p/5706496.html https://www.cnblogs.com/shiyingzhi/p/7896 ...
- Visual Studio 2013 突然不高亮,编译报错
同事的电脑,估计是windows更新失败的原因,C盘容量减小到不到1G,VS的高亮也坏了,重启后硬盘容量增加了但是仍然不高亮. 解决办法记录一下: 重置下. 开始菜单 -->所有程序--> ...
- js分析 有_道_翻_译 md5
0.参考 1.分析 1.1 输入翻译内容,手动点击“翻译”按钮 1.2 查看提交数据,通过多次提交确认变化量 1.3 CTRL+SHIFT+f 全局搜索 salt 或 sign 定位到三处js代码块, ...
- SQL反模式学习笔记7 多态关联
目标:引用多个父表 反模式:使用多用途外键.这种设计也叫做多态关联,或者杂乱关联. 多态关联和EAV有着相似的特征:元数据对象的名字是存储在字符串中的. 在多态关联中,父表的名字是存储在Issue_T ...
- SQL反模式学习笔记15 分组
目标:查询得到每组的max(或者min等其他聚合函数)值,并且得到这个行的其他字段 反模式:引用非分组列 单值规则:跟在Select之后的选择列表中的每一列,对于每个分组来说都必须返回且仅返回一直值. ...