双向链表的插入删除和遍历

本文详细介绍了使用C语言实现双向链表的过程,包括节点的创建、插入、删除以及遍历等核心操作。通过具体示例,展示了如何在双向链表中进行头插、尾插和中间插入,并解释了节点删除的步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define OVERFLOW -2
#define FALSE 0
#define TRUE 1
#define OK 1
#define ERROR 0

typedef int Status;
//链表元素的数据类型
typedef struct
{
	char name[20];
	float score;
}ElemType;

//线性链表的双向链表存储结构
typedef struct
{
	ElemType data;
	struct Dnode *next;   //存放后继结点地址
	struct Dnode *pre;    //存放前驱结点地址
}Dnode,*DLinkList;

int main()
{
	DLinkList L,p,q,s;
	ElemType e1,e2,e3,e4;
	L=(DLinkList)malloc(sizeof(Dnode));
	L->next=L->pre=L;

	strcpy(e1.name,"宇文");
	strcpy(e2.name,"化及");
	strcpy(e3.name,"长孙");
	strcpy(e4.name,"无忌");
	e1.score=87.44;
	e2.score=69.22;
	e3.score=56.33;
	e4.score=89.22;
	
	p=L;
	s=(DLinkList)malloc(sizeof(Dnode));
	s->data=e1;
	s->next=p->next; s->pre=p;    //生成的节点右边连线,左边连线
//	p->next->pre=s; //这一步就不需要了,因为pre还不存在,表中只有一个头结点
// 经过发现不是不需要,编译器报错的原因是,识别不了你是什么意思,可以分两步来写
	q=p->next; q->pre=s;         //生成节点的后继节点左边连线
	p->next=s;                   //生成节点的前驱节点右边连线

	p=L;         //头插
	s=(DLinkList)malloc(sizeof(Dnode));
	s->data=e2;
	s->next=p->next; s->pre=p;	
	q->pre=s;q=p->next;
	p->next=s;
	
	q=L->next;   //尾插
	p=q->next;
	s=(DLinkList)malloc(sizeof(Dnode));
	s->data=e3;
	s->next=p->next; s->pre=p;	
	q->pre=s;q=p->next;
	p->next=s;
				
	p=L->next;    //插入到第一个节点和第二个节点之间
	s=(DLinkList)malloc(sizeof(Dnode));
	s->data=e4;
	s->next=p->next; s->pre=p;	
	q->pre=s;q=p->next;
	p->next=s;

	p=L->next;
	while(p!=L)
	{
		printf("姓名:%s 分数:%4.2f 地址:%x,房间大小:%d,pre %x next %x \n",p->data.name,p->data.score,p,sizeof(Dnode),p->pre,p->next);
		p=p->next;
	}
}

运行结果
在这里插入图片描述

//删除第i个结点
Status deleteDLinkList(DLinkList L,int i,ElemType *e)
{
	DLinkList p,q;
	int j;
	p=L;j=0;
	
	//p指向第i-1个结点,又要确保不是空表
	if(p->next==L||j>i-1)
	{
		printf("删除位置不合理或链表为空!\n");
		return ERROR;
	}
	while(p->next!=L && j<i-1) //p为空表或者到达i-1这个位置,就停止了
	{
		p=p->next;
		j++;
	}
	q=p->next;   //q为要删除的节点
	*x=q->data;
	p->next=q->next; //q的前驱节点越过q连接q的下一个节点
	q->next->pre=p;  //q的后记节点越过q连接q的前驱节点
	free(q);
	return OK;
}
//指定遍历方向,遍历所有数据
void dispDLinkList(DLinkList L,int n)
{
	DLinkList p;
	if(n==1{
		p=L->next;
		while(p!=L)
		{
			printf(p->data);
			p=p->next;
		}
		printf("\n");
	}
	if(n==2)
	{
		p=L->pre;
		while(p!=L)
		{
			printf(p->data);
			p=p->pre;
		}
		printf("\n");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值