C语言数据结构 双向链表的建立与基本操作

双向链表比单链表有更好的灵活性,其大部分操作与线性表相同。下面总结双向链表与单链表之间的不同之处及我在实现过程中所遇到的问题。
1.双向链表的建立
双向链表在初始化时,要给首尾两个节点分配内存空间。成功分配后,要将首节点的prior指针和尾节点的next指针指向NULL,这是十分关键的一步,因为这是之后用来判断空表的条件。同时,当链表为空时,要将首节点的next指向尾节点,尾节点的prior指向首节点。
2.双向链表的插入操作
由于定义双向链表时指针域中多了一个prior指针,插入操作相应变得复杂,但基本操作也并不难理解。只需记住在处理前驱和后继指针与插入节点的关系时,应始终把握好“有序原则”,即若将插入节点与两个已存在的节点构成三角形,则应先处理“向上”的指针,再处理“向下”的指针。下面用代码描述其过程:
pinsert->prior=p; pinsert->next=p->next; p->next->prior=pinsert; p->next=pinsert;
3.双向链表的删除操作
理解了双向链表的插入操作后,删除操作便十分容易理解。下面用代码描述其过程:
p->prior->next=p->next; p->next->prior=p->prior; free(p);
双向链表的其他操作与单链表类似,在此不再赘述,完整的代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int status;
typedef int elemtype;
typedef struct node{
elemtype data;
struct node * next;
struct node * prior;
}node;
typedef struct node* dlinklist;
status visit(elemtype c){
printf("%d ",c);
}
/*双向链表初始化*/
status initdlinklist(dlinklist * head,dlinklist * tail){
(*head)=(dlinklist)malloc(sizeof(node));
(*tail)=(dlinklist)malloc(sizeof(node));
if(!(*head)||!(*tail))
return ERROR;
/*这一步很关键*/
(*head)->prior=NULL;
(*tail)->next=NULL;
/*链表为空时让头指向尾*/
(*head)->next=(*tail);
(*tail)->prior=(*head);
}
/*判定是否为空*/
status emptylinklist(dlinklist head,dlinklist tail){
if(head->next==tail)
return TRUE;
else
return FALSE;
}
/*尾插法创建链表*/
status createdlinklisttail(dlinklist head,dlinklist tail,elemtype data){
dlinklist pmove=tail,pinsert;
pinsert=(dlinklist)malloc(sizeof(node));
if(!pinsert)
return ERROR;
pinsert->data=data;
pinsert->next=NULL;
pinsert->prior=NULL;
tail->prior->next=pinsert;
pinsert->prior=tail->prior;
pinsert->next=tail;
tail->prior=pinsert;
}
/*头插法创建链表*/
status createdlinklisthead(dlinklist head,dlinklist tail,elemtype data){
dlinklist pmove=head,qmove=tail,pinsert;
pinsert=(dlinklist)malloc(sizeof(node));
if(!pinsert)
return ERROR;
else{
pinsert->data=data;
pinsert->prior=pmove;
pinsert->next=pmove->next;
pmove->next->prior=pinsert;
pmove->next=pinsert;
}
}
/*正序打印链表*/
status traverselist(dlinklist head,dlinklist tail){
/*dlinklist pmove=head->next;
while(pmove!=tail){
printf("%d ",pmove->data);
pmove=pmove->next;
}
printf("\n");
return OK;*/
dlinklist pmove=head->next;
while(pmove!=tail){
visit(pmove->data);
pmove=pmove->next;
}
printf("\n");
}
/*返回第一个值为data的元素的位序*/
status locateelem(dlinklist head,dlinklist tail,elemtype data){
dlinklist pmove=head->next;
int pos=1;
while(pmove&&pmove->data!=data){
pmove=pmove->next;
pos++;
}
return pos;
}
/*返回表长*/
status listlength(dlinklist head,dlinklist tail){
dlinklist pmove=head->next;
int length=0;
while(pmove!=tail){
pmove=pmove->next;
length++;
}
return length;
}
/*逆序打印链表*/
status inverse(dlinklist head,dlinklist tail){
dlinklist pmove=tail->prior;
while(pmove!=head){
visit(pmove->data);
pmove=pmove->prior;
}
printf("\n");
}
/*删除链表中第pos个位置的元素,并用data返回*/
status deleteelem(dlinklist head,dlinklist tail,int pos,elemtype *data){
int i=1;
dlinklist pmove=head->next;
while(pmove&&i<pos){
pmove=pmove->next;
i++;
}
if(!pmove||i>pos){
printf("输入数据非法\n");
return ERROR;
}
else{
*data=pmove->data;
pmove->next->prior=pmove->prior;
pmove->prior->next=pmove->next;
free(pmove);
}
}
/*在链表尾插入元素*/
status inserttail(dlinklist head,dlinklist tail,elemtype data){
dlinklist pinsert;
pinsert=(dlinklist)malloc(sizeof(node));
pinsert->data=data;
pinsert->next=NULL;
pinsert->prior=NULL;
tail->prior->next=pinsert;
pinsert->prior=tail->prior;
pinsert->next=tail;
tail->prior=pinsert;
return OK;
}
int main(void){
dlinklist head,tail;
int i=0;
elemtype data=0;
initdlinklist(&head,&tail);
if(emptylinklist(head,tail))
printf("链表为空\n");
else
printf("链表不为空\n");
printf("头插法创建链表\n");
for(i=0;i<10;i++){
createdlinklisthead(head,tail,i);
}
traverselist(head,tail);
for(i=0;i<10;i++){
printf("表中值为%d的元素的位置为",i);
printf("%d位\n",locateelem(head,tail,i));
}
printf("表长为%d\n",listlength(head,tail));
printf("逆序打印链表");
inverse(head,tail);
for(i=0;i<10;i++){
deleteelem(head,tail,1,&data);
printf("被删除的元素为%d\n",data);
}
traverselist(head,tail);
if(emptylinklist(head,tail))
printf("链表为空\n");
else
printf("链表不为空\n");
printf("尾插法创建链表\n");
for(i=0;i<10;i++){
//inserttail(head,tail,i);
createdlinklisttail(head,tail,i);
}
traverselist(head,tail);
printf("逆序打印链表");
inverse(head,tail);
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# C语言数据结构
# 双向链表详解
# 双向链表实例并分析
# C语言双向链表的原理与使用操作
# C语言算法学习之双向链表详解
# C语言类的双向链表详解
# C语言中双向链表和双向循环链表详解
# C语言实现数据结构和双向链表操作
# C语言 数据结构双向链表简单实例
# C语言之双向链表详解及实例代码
# C语言实现双向链表
# C语言超详细i讲解双向链表
# 链表
# 为空
# 这是
# 要将
# 值为
# 角形
# 我在
# 第一个
# 在此
# 只需
# 数据结构
# 希望能
# 要给
# 谢谢大家
# 把握好
# 过程中
# 则应
# 不同之处
# 并不难
# 线性表
相关文章:
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
如何在建站主机中优化服务器配置?
成都响应式网站开发,dw怎么把手机适应页面变成网页?
三星网站视频制作教程下载,三星w23网页如何全屏?
已有域名和空间如何搭建网站?
合肥做个网站多少钱,合肥本地有没有比较靠谱的交友平台?
建站之星北京办公室:智能建站系统与小程序生成方案解析
建站之星ASP如何实现CMS高效搭建与安全管理?
建站主机SSH密钥生成步骤及常见问题解答?
如何确认建站备案号应放置的具体位置?
临沂网站制作企业,临沂第三中学官方网站?
建站为何优先选择香港服务器?
北京制作网站的公司,北京铁路集团官方网站?
清单制作人网站有哪些,近日“兴风作浪的姑奶奶”引起很多人的关注这是什么事情?
python的本地网站制作,如何创建本地站点?
建站主机空间推荐 高性价比配置与快速部署方案解析
如何在西部数码注册域名并快速搭建网站?
招贴海报怎么做,什么是海报招贴?
建站之星2.7模板:企业网站建设与h5定制设计专题
网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?
建站之星安全性能如何?防护体系能否抵御黑客入侵?
深圳网站制作平台,深圳市做网站好的公司有哪些?
IOS倒计时设置UIButton标题title的抖动问题
学校免费自助建站系统:智能生成+拖拽设计+多端适配
建站之星后台密码遗忘?如何快速找回?
免费网站制作appp,免费制作app哪个平台好?
如何在腾讯云免费申请建站?
如何用西部建站助手快速创建专业网站?
定制建站流程解析:需求评估与SEO优化功能开发指南
如何快速辨别茅台真假?关键步骤解析
官网网站制作腾讯审核要多久,联想路由器newifi官网
seo网站制作优化,网站SEO优化步骤有哪些?
,有什么在线背英语单词效率比较高的网站?
建站之星后台密码如何安全设置与找回?
建站之星如何助力企业快速打造五合一网站?
我的世界制作壁纸网站下载,手机怎么换我的世界壁纸?
如何在Golang中处理模块冲突_解决依赖版本不兼容问题
胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?
如何快速搭建高效服务器建站系统?
定制建站哪家更专业可靠?推荐榜单揭晓
如何高效完成自助建站业务培训?
国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?
宝塔新建站点报错如何解决?
html制作网站的步骤有哪些,iapp如何添加网页?
高端建站三要素:定制模板、企业官网与响应式设计优化
公司网站制作费用多少,为公司建立一个网站需要哪些费用?
微信小程序 input输入框控件详解及实例(多种示例)
建站之星免费版是否永久可用?
东莞专业制作网站的公司,东莞大学生网的网址是什么?
全景视频制作网站有哪些,全景图怎么做成网页?
*请认真填写需求信息,我们会在24小时内与您取得联系。