#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. 脚本化CSS(通过JS来间接操作CSS)

    (一)通过.style.形式,获取的是行间样式,可读可写 1.行间样式语法 1 <div style="width:100px;border:5px solid red;height: ...

  2. redis跳表

    redis使用跳表作为有序集合的底层实现之一,下面来看下跳表的结构 一.跳表的结构

  3. 5分钟学Go 基础01:初识 Go 的第一印象是薪水可观

    本文首发于公众号「5分钟学Go」,一个让你每次花 5 分钟就能掌握一个技能点的公众号.目前在博主连更 5 分钟学Go系列,大家可以关注下,第一时间掌握Go技能.如果想要加群交流,可以在公众号后台回复「 ...

  4. Vue & Sentry & ErrorHandler

    Vue & Sentry & ErrorHandler import * as Sentry from '@sentry/browser'; import { Vue as VueIn ...

  5. css position sticky All In One

    css position sticky All In One css sticky & 吸顶效果 demo https://codepen.io/xgqfrms/pen/PoqyVYz ref ...

  6. js screen size check

    js screen size check js 屏幕尺寸检测 window.screen API screen; window.screen.width; window.screen.height; ...

  7. 使用 js 实现十大排序算法: 希尔排序

    使用 js 实现十大排序算法: 希尔排序 希尔排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  8. WebVR & CSS 3D & WebGL

    WebVR & CSS 3D & WebGL VR https://developer.mozilla.org/en-US/docs/Web/API/WebVR_API https:/ ...

  9. switchable css dark theme in js & html custom element

    switchable css dark theme in js & html custom element dark theme / dark mode https://codepen.io/ ...

  10. 基本ILS面的评估

    一.定义与用途 基本ILS面是ICAO DOC8168飞行程序设计规范中提到的一种限制面. 它相当于附件14中代码为3或4的精密进近跑道所规定的障碍物限制面的子集. 包含:进近面(分为两部分).过渡面 ...