链表大概分为有无头指针,有无尾指针,是否循环,单向还是双向,

这些都很简单,前提是你要把指针和单链表理解透彻。这些都是基于单链表

的变形,要根据实际问题,选择链表的类型。

  头指针的指针域储存着储存头节点的地址,其数据域我们不使用。

尾指针同理。

  循环链表的最后一个节点指向头节点(如果有头指针,则是指向头指针),

非循环链表的最后一个节点指向NUll。

  单向链表只有一个指针域,且指向下一个节点地址,

而双向链表有两个指针域,一个指向该节点的上一个节点地址,

另一个指向该节点的下一个节点地址。  

  构建链表节点:

 #define ElemType int //链表元素类型

 //线性表的双向链表储存结构
typedef struct DuLNode {
ElemType data; //数据域
struct DuLNode *prior; //前驱指针域
struct DuLNode *next; //后继指针域 }DuLNode;

  如果d为指向链表中某一个节点的指针  则显然满足

d->next->prior=d->prior->next=d
//d->next 表示d的上一个节点
//d->next->prior 表示d的上一个节点的下一个节点 即d本身
//-_-!有点绕啊

  双向循环链表中有一些操作只需要一个方向的指针,比如计算链表长度(这里全局变量iCount即为长度),

查找元素,返回元素位置等等(这些我都不想写 请原谅我的懒-_-)  ,当然涉及两个方向的指针我都会贴出来的。

  

 #include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define ElemType int //链表元素类型
int iCount; // 定义全局变量 表示链表长度
//线性表的双向链表储存结构
typedef struct DuLNode {
ElemType data; //数据域
struct DuLNode *prior; //前驱指针域
struct DuLNode *next; //后继指针域 }DuLNode;
//创建链表
DuLNode *CreateDuLNode() {
DuLNode *pHead , *pEnd, *pNew;
//头指针的初始化
pHead=(DuLNode*)malloc(sizeof(DuLNode));
pHead->prior = NULL;
pHead->next = NULL;
if (!pHead) exit(); pNew = pEnd = (DuLNode*)malloc(sizeof(DuLNode));
if (!pNew) exit();
scanf("%d", &pNew->data);
while (pNew->data != ) //读取到0结束
{
iCount++;
if (iCount == )
{
pNew->prior= pHead;
pNew->next = NULL;
pHead->next = pNew;
pEnd = pNew; }
else
{
pNew->prior = pEnd;
pNew->next = NULL;
pEnd->next = pNew;
pEnd = pNew;
}
pNew = (DuLNode*)malloc(sizeof(DuLNode));
if (!pNew) exit();
scanf("%d", &pNew->data); }
free(pNew); //释放多余的空间
pHead->prior = pEnd; //形成
pEnd->next = pHead; // 双循环
return pHead;
}
//插入节点
int DuLInsert(DuLNode *p, int i, DuLNode *s) {
/*在带头指针的的双链循环线性表p中的第i个位置
之前插入节点s,i的合法值为1<=i<=表长(头指针不算长度)+1
i取最小值头插,i取最大值尾插*/
DuLNode *q;
if (i< || i>iCount + ) //i的值不合法
return ERROR; if (i == iCount + ) //在p中确定第i个元素的位置 指针q
q = p;
else
for (q = p; i > ; i--)
q = q->next;
//先插入 后修改 防止断链
q->prior->next = s;
s->prior = q->prior;
q->prior = s;
s->next = q; return OK;
}
//删除第i个节点,并用e返回删除值
int DuLDelete(DuLNode *p, int i, ElemType *e) {
/*在带头指针的的双链循环线性表p中的第i个位置
之前插入节点s,i的合法值为1<=i<=表长(头指针不算长度)+1
i取最小值头删,i取最大值尾删*/
DuLNode *q;
if (i< || i>iCount + ) //i的值不合法
return ERROR; //在p中确定第i个元素的位置 指针q
for (q = p; i > ; i--)
q = q->next; *e = q->data;
q->prior->next = q->next;
q->next->prior = q->prior;
free(q); return OK;
}

双向循环链表涉及双向指针的基本操作(C语言)的更多相关文章

  1. C语言通用双向循环链表操作函数集

    说明 相比Linux内核链表宿主结构可有多个链表结构的优点,本函数集侧重封装性和易用性,而灵活性和效率有所降低.     可基于该函数集方便地构造栈或队列集.     本函数集暂未考虑并发保护. 一  ...

  2. (java实现)双向循环链表

    什么是双向循环链表 在了解双向循环链表之前,如果对链表还没有一个清晰的概念,建议你看看单链表和单向循环链表,这有利于你更好的理解下面的内容.(废话有点多[逃] 相比单链表,双向循环链表是一个更加复杂的 ...

  3. C++实现双向循环链表

    本次博文是关于利用C++模板的方式实现的双向循环链表以及双向循环链表的基本操作,在之前的博文C++语言实现双向链表中,已经给大家分析了双向循环链表的结构,并以图示的方式给大家解释了双向循环链表的基本操 ...

  4. 【C语言教程】“双向循环链表”学习总结和C语言代码实现!

    双向循环链表 定义 双向循环链表和它名字的表意一样,就是把双向链表的两头连接,使其成为了一个环状链表.只需要将表中最后一个节点的next指针指向头节点,头节点的prior指针指向尾节点,链表就能成环儿 ...

  5. python实现 双向循环链表

    最近身边的朋友在研究用python来实现数据结构.遇到一个问题就是双向循环链表的实现,改指向的时候总是发蒙. 我自己尝实现了一个python的双向循环链表.附上代码,希望对大家有帮助. 如果不懂什么是 ...

  6. (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作

    双向循环链表是基于双向链表的基础上实现的,和双向链表的操作差不多,唯一的区别就是它是个循环的链表,通过每个节点的两个指针把它们扣在一起组成一个环状.所以呢,每个节点都有前驱节点和后继节点(包括头节点和 ...

  7. 双向链表、双向循环链表的JS实现

    关于链表简介.单链表.单向循环链表.JS中的使用以及扩充方法:  单链表.循环链表的JS实现 关于四种链表的完整封装: https://github.com/zhuwq585/Data-Structu ...

  8. 双向循环链表的Java版本实现

    1.单项循环列表 单向循环链表是单链表的另一种形式,其结构特点是链表中最后一个结点的指针不再是结束标记,而是指向整个链表的第一个结点,从而使单链表形成一个环.和单链表相比,循环单链表的长处是从链尾到链 ...

  9. java与数据结构(4)---java实现双向循环链表

    线性表之链式存储结构双向循环链表 双向循环链表:每个结点包含了数据.直接前驱地址指针和直接后驱地址指针,头结点的直接前驱指向尾结点,尾结点的直接后驱指向头结点,头尾相连构成一个可正可反的圆环.可以形象 ...

随机推荐

  1. as3.0复制影片简介(自我复制的三种形式)

    //mc是被复制影片简介的实例名,(===在库中找到mc影片简介,右击“属性”,点击“为actionscript导出”,选中确定即可===这个是重点) var newSprite:Sprite=mc; ...

  2. no module named cv2

    运行python脚本时报错: ImportError: No module named cv2 第一想法: 使用命令: pip install cv2 会报错找不到请求的版本 解决方法: 使用命令 p ...

  3. 2018蓝桥杯 全球变暖(dfs)

    你有一张某海域NxN像素的照片,"."表示海洋."#"表示陆地,如下所示:........##.....##........##...####....###.. ...

  4. Linux磁盘挂载详述

    1.查看硬盘信息及分区 一般使用”fdisk -l”命令可以列出系统中当前连接的硬盘,设备和分区信息.新硬盘没有分区信息,则只显示硬盘大小信息. [root@localhost home]# fdis ...

  5. 4-java 格式化输出

    java保留两位小数4种方法 import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberF ...

  6. mysql 数据库备份的多种方式

    一.使用mysqldump进行备份 1.完整备份所有数据库 mysqldump -u root -p --all-databases > E:/all.sql 在mysql8之前,存储过程和事件 ...

  7. go语言中的并发

    package main; import ( "fmt" "runtime" "sync" ) //goruntine奉行通过通信来共享内存 ...

  8. 使用PHP来简单的创建一个RPC服务

    RPC全称为Remote Procedure Call,翻译过来为"远程过程调用".主要应用于不同的系统之间的远程通信和相互调用. 比如有两个系统,一个是PHP写的,一个是JAVA ...

  9. sqlite c#

    https://www.cnblogs.com/icebutterfly/p/7850689.html https://www.cnblogs.com/sdadx/p/7127098.html

  10. c#devexpress GridContorl datasource为 类字段的实现方式 非datatable方式以及其他操作总结

    1:定义model class A { public string a{get;set;} public string b{get;set;} } 2:赋值: A aobj=new A(); aobj ...