#include <stdio.h>
#include <stdlib.h> /**
* 含头节点双向链表定义及有关操作
*/ //操作函数用到的状态码
#define TRUE 1;
#define FALSE 0;
#define OK 1;
#define ERROR 0; //Status是新定义的一种函数返回值类型,其值为int型,意义为函数结果 状态码
typedef int Status;
//定义一种 数据元素 类型,为表示方便,定义为char型
typedef char ElemType; //双向链表的定义
typedef struct DuLnode {
ElemType data;
struct DuLnode *next,*prior;
} DuLnode, *DuLinkList; //操作1:双向链表初始化
Status InitList(DuLinkList *list){
(*list)=(DuLinkList)malloc(sizeof(DuLnode));
(*list)->prior=NULL;
(*list)->next=NULL;
return OK;
} //操作2:头插法建立双向链表,数据保存在ElemType类型的数组中
Status CreateList_H(DuLinkList *list,ElemType arrData[],int length){
int j;
for(j=length-1;j>=0;j--){
//新建结点并分配空间
DuLnode *node;
node=(DuLnode*)malloc(sizeof(DuLnode));
node->data=arrData[j];
node->prior=NULL;
node->next=NULL; //插入为1号结点
node->next=(*list)->next;
node->prior=(*list);
if((*list)->next){ //第一个结点已存在
(*list)->next->prior=node;
}
(*list)->next=node;
}
return OK;
} //操作3:尾插法建立双向链表
Status CreateList_R(DuLinkList *list,ElemType arrData[],int length) {
int j;
DuLnode *r; //尾指针
r=*list;
for(j=0;j<length;j++) {
DuLnode *node;
node=(DuLnode*)malloc(sizeof(DuLnode));
node->data=arrData[j];
node->prior=NULL;
node->next=NULL; //插入表尾
r->next=node;
node->prior=r;
r=node; //r指向尾结点
}
return OK;
} //操作4:双向链表元素遍历输出
Status ListTraverse(DuLinkList list) {
DuLnode *p;
p=list;
int j=0;
printf("逻辑索引: 结点数据:\n");
while(p->next){
j++;
p=p->next;
printf(" %d %c\n",j,p->data);
}
return OK;
} //操作5:插入新元素数据到指定位置。(i为逻辑位置)
Status ListInsert(DuLinkList *list,int i,ElemType elem){
if(i<1) return ERROR; //插入位置序号小于1
DuLnode *p;
int j=0; //计数器
p=*list;
//先找到第i-1个结点
while(p&&j<i-1){
j++;
p=p->next;
}
if(!p) return ERROR; //构造新结点
DuLnode *new_node;
new_node=(DuLnode*)malloc(sizeof(DuLnode));
new_node->data=elem; //插入到链表
if(p->next){ //当i!=length+1时,即非插入尾结点之后时。
new_node->next=p->next;
p->next->prior=new_node;
}
new_node->prior=p;
p->next=new_node; return OK;
} //操作6:删除链表第i个结点,被删除的数据保存在elem
Status ListDelete(DuLinkList *list,int i,ElemType *elem){
if(i<1) return ERROR;
DuLnode *p; //工作指针指向待删结点
int j=1; //计数器
p=(*list)->next; //指向首元
while(p&&j<i) {
p=p->next;
j++;
}
if(!p) return ERROR; //i>length //删除结点
p->prior->next=p->next;
if(p->next){
p->next->prior=p->prior; //若删除的不是尾结点
} free(p);
return OK;
} //其他操作(如:判空、销毁、清空、求表长、按值查找、遍历输出、索引到数据等)由于不涉及或只涉及一个方向,故与单链表的操作无异。 int main(void){
//定义一个双向链表(用指针list1表示)
DuLinkList list1; //链表初始化
Status initResultCode=InitList(&list1);
printf("list1初始化结果:%d\n",initResultCode); //产生数据并保存到数组
ElemType data1='A',data2='B',data3='C',data4='D',data5='E',data6='F';
ElemType waitInserted[]={
data1,
data2,
data3,
data4,
data5,
data6,
};
//获得数组长度
int arrLength=sizeof(waitInserted)/sizeof(waitInserted[0]); //头插法建立链表list1
Status createListResult1 = CreateList_H(&list1,waitInserted,arrLength);
printf("建表结果状态码:%d\n",createListResult1);
ListTraverse(list1); //遍历测试 //定义表2
DuLinkList list2;
InitList(&list2);
//尾插法建立链表list2
CreateList_R(&list2,waitInserted,arrLength);
ListTraverse(list2); //遍历测试 //插入结点
ElemType elemInserted='T';
Status insertResultCode = ListInsert(&list1,1,elemInserted);
printf("插入结果状态码:%d\n",insertResultCode);
ListTraverse(list1); //遍历测试 //删除结点,并保存删除的数据
ElemType deletedElem;
Status deleteResultCode=ListDelete(&list1,2,&deletedElem);
printf("删除结果状态码:%d\n",deleteResultCode);
printf("被删除结点数据:%c\n",deletedElem);
ListTraverse(list1); //遍历测试 printf("\nEND!");
return 0;
}

双向链表及有关操作(C语言)的更多相关文章

  1. 双向链表的实现与操作(C语言实现)

    双向链表也叫双链表,是链表的一种,它的每一个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的随意一个结点開始,都能够非常方便地訪问它的前驱结点和后继结点. 单链表的局限 1.单 ...

  2. neo4j初次使用学习简单操作-cypher语言使用

    Neo4j 使用cypher语言进行操作 Cypher语言是在学习Neo4j时用到数据库操作语言(DML),涵盖对图数据的增删改查  neo4j数据库简单除暴理解的概念: Neo4j中不存在表的概念, ...

  3. 栈的实现与操作(C语言实现)

    栈的定义  1, 栈是一种特殊的线性表  2,栈仅能在线性表的一端进行操作  3,栈顶(Top): 同意操作的一端 同意操作的一端  4,栈底(Bottom): ,不同意操作的一端 不同意操作 ...

  4. 1.Go语言copy函数、sort排序、双向链表、list操作和双向循环链表

    1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 package main import "fmt" func main() ...

  5. 1.Go-copy函数、sort排序、双向链表、list操作和双向循环链表

    1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 ? 1 2 3 4 5 6 7 8 9 10 11 12 package main   imp ...

  6. 【C语言教程】双向链表学习总结和C语言代码实现!值得学习~

    双向链表 定义 我们一开始学习的链表中各节点中都只包含一个指针(游标),且都统一指向直接后继节点,通常称这类链表为单向链表. 虽然使用单向链表能 100% 解决逻辑关系为 "一对一" ...

  7. 动态单链表的传统存储方式和10种常见操作-C语言实现

    顺序线性表的优点:方便存取(随机的),特点是物理位置和逻辑为主都是连续的(相邻).但是也有不足,比如:前面的插入和删除算法,需要移动大量元素,浪费时间,那么链式线性表 (简称链表) 就能解决这个问题. ...

  8. Gremlin--一种支持对图表操作的语言

    Gremlin 是操作图表的一个非常有用的图灵完备的编程语言.它是一种Java DSL语言,对图表进行查询.分析和操作时使用了大量的XPath. Gremlin可用于创建多关系图表.因为图表.顶点和边 ...

  9. 动态分配的顺序线性表的十五种操作—C语言实现

    线性表 定义:是最常用的,也是最简单的数据结构,是长度为n个数据元素的有序的序列. 含有大量记录的线性表叫文件 记录:稍微复杂的线性表里,数据元素为若干个数据项组成,这时把一个数据元素叫记录 结构特点 ...

随机推荐

  1. Python——处理CSV、PDF文件

    一.CSV文件处理 (1)读取 import csv filename = "E:/GitHub/Python-Learning/LIVE_PYTHON/2018-06-05/学位英语成绩合 ...

  2. MHA 的 Binlog Server & VIP 漂移

    目录 Binlog Server 在 MHA 配置文件中配置 Binlog Server 创建 Binlog 存放目录 实时传输主库 Binlog 命令 重启 MHA 检验 MHA Manager 服 ...

  3. JVM ZeroTLAB 是什么意思呢?

    ZeroTLAB 是 JVM 的一个布尔型 Flag,意思是是否将新创建的 TLAB 内的所有字节归零. 默认:false 举例:-XX:+ZeroTLAB 当分配出来 TLAB 之后,根据 Zero ...

  4. LeetCode6 Z字形排列

    题目描述是从上到下,从左到右Z字形排列. 找规律.这种形式一般都是mod x 余数有规律.然后写的时候围绕x构造,而非判断,代码会简单一些. 设行数为r 先观察r=5的情况 发现第0行的字符原始ind ...

  5. C++含有无符号类型的表达式的计算

    unsigned u=10; int i=-42; cout<<i+i<<endl; cout<<u+i<<endl; 在第二个输出表达式中,相加前首先 ...

  6. SpringBoot 全局视角看springboot

    从单体架构到微服务 单体架构 任何一个网站在发布初期几乎都不可能立马就拥有庞大的用户流量和海量数据,都是在不停 的试错过程中一步一步演变其自身架构,满足其自身业务.比如现在能够抗住双十一这么大 流量的 ...

  7. HDU 3949 XOR (线性基第k小)题解

    题意: 给出\(n\)个数,求出子集异或第\(k\)小的值,不存在输出-1. 思路: 先用线性基存所有的子集,然后对线性基每一位进行消元,保证只有\(d[i]\)的\(i\)位存在1,那么这样变成了一 ...

  8. 产品经理进阶:如何用UML的顺序图表达思想?

    当大家把UML建模语言下的各图形都有所了解后会发现,通过这些图可以全面的.立体的从各个角度表达产品,让产品的表达变得更丰富.更形象. "手中无剑.心中有剑",大多数产品人并不了解计 ...

  9. Flutter Widget API

    Flutter Widget API https://api.flutter.dev/ https://api.flutter.dev/flutter/material/material-librar ...

  10. css delete line text & html del

    css delete line text & html del html <del>¥720</del> demo <span class="ticke ...