数据结构学习:单链表的基本操作之插入与删除

数据结构学习:单链表的基本操作

单链表的基本操作

单链表的基本操作之插入
ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。
即将插入位置的前一个节点的指针指向插入节点,插入节点的指针指向原来第i个位置的节点
插入前:
在这里插入图片描述
插入后:
在这里插入图片描述

//在带头结点的链表的第i个位置插入元素e
bool ListInsert(LinkList &L,int i, ElemType e)
{
	if(i<1)
		return false;
	LNode *p;			//定义一个指针p
	int j = 0;			//用来标注指针p指向的第几个结点
	p = L;				//L指向头指针,头指针是第0个结点,将p指向头指针
	while(p != NULL && j<i-1)		//通过循环来找到第i-1个结点
	{
		p = p->next;
		j++;
	}
	if(p == NULL)		//i值不合法
		return false;
	//此时的p指向的是要插入位置的前一个结点
	LNode *s = (LNode *)malloc(sizeof(LNode));//定义一个结点s用来插入;
	s->data = e;		//将e赋值给结点s的数据域
	s->next = p->next;	//将要插入位置的下一个结点的地址赋给s结点的指针域
	p->next = s;		//插入位置的前一个结点的指针域指向插入的结点
	return true;		//插入成功
	//可以直接调用后插方法,两种方法效果一样
	//InsertNextNode(p,e);
}
//后插操作:在结点p之后插入元素e
bool InsertNextNode(LNode *p,ElemType e)
{
	if(p == NULL)		//p值不合法
		return false;
	//此时的p指向的是要插入位置的前一个结点
	LNode *s = (LNode *)malloc(sizeof(LNode));//定义一个结点s用来插入;
	if(s == NULL)		//内存分配失败
		return false;
	s->data = e;		//将e赋值给结点s的数据域
	s->next = p->next;	//将要插入位置的下一个结点的地址赋给s结点的指针域
	p->next = s;		//插入位置的前一个结点的指针域指向插入的结点
	return true;		//插入成功
}
//在不带头结点的链表的第i个位置插入元素e
bool ListInsert(LinkList &L,int i, ElemType e)
{
	if(i<1)
		return false;
		
	if(i == 1)//如果要插入的位置为第一个结点
	{
		LNode *s = (LNode *)malloc(sizeof(LNode));//定义一个结点s用来插入;
		s->data = e;	//将要插入的值e赋值给结点s的数据域
		s->next = L;	//将头指针L指向的地址赋给s结点的指针域
		L = s;			//头指针L指向s结点
		return true;
	}
	LNode *p;			//定义一个指针p
	int j = 1;			//用来标注指针p指向的第几个结点
	p = L;				//p指向第一个结点
	while(p != NULL && j<i-1)		//通过循环来找到第i-1个结点
	{
		p = p->next;
		j++;
	}
	if(p == NULL)		//i值不合法
		return false;
	//此时的p指向的是要插入位置的前一个结点
	LNode *s = (LNode *)malloc(sizeof(LNode));//定义一个结点s用来插入;
	s->data = e;		//将e赋值给结点s的数据域
	s->next = p->next;	//将要插入位置的下一个结点的地址赋给s结点的指针域
	p->next = s;		//插入位置的前一个结点的指针域指向插入的结点
	return true;		//插入成功
}

带不带头指针的链表的后插操作是一样的

前插操作可以看做后插操作后交换两结点的数据域的值

//在结点p前插一个值为e
bool InsertPriorNode(LNode *p,ElemType e)
{
	
	if(p == NULL)		//p值不合法
		return false;
	LNode *s = (LNode *)malloc(sizeof(LNode));//定义一个结点s用来插入;
	if(s == NULL)		//内存分配失败
		return false;
	
	//实现后插
	s->next = p->next;	//将要插入位置的下一个结点的地址赋给s结点的指针域
	p->next = s;		//插入位置的结点的指针域指向插入的结点
	//后插后交换数据等同于前插
	s->data = p->data;	//将p结点赋值给结点s的数据域
	p->data = e;		//将e的值赋给p结点
	return true;		//插入成功
}
//在结点p前插一个结点s
bool InsertPriorNode(LNode *p,LNode *s)
{
	
	if(p == NULL || s == NULL)		//p结点与s结点不合法
		return false;
	
	//实现后插
	s->next = p->next;	//将要插入位置的下一个结点的地址赋给s结点的指针域
	p->next = s;		//插入位置的结点的指针域指向插入的结点
	
	//后插后交换数据等同于前插
	ElemType temp = s->date
	s->data = p->data;	//将p结点赋值给结点s的数据域
	p->data = temp;		//将s结点的值赋给p结点
	return true;		//插入成功
}

单链表的基本操作之删除
ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。

原理:
找到第 i-1 个结点,将其指针指向第i+1个结点,并释放第i个结点

//删除操作
bool ListDetele(LinkList &L,int i,ElemType &e)
//在链表L中删除第i个结点,并将其值返回为e
{
	if(i<1)
		return false;
	LNode *p;			//定义一个指针p
	int j = 0;			//用来标注指针p指向的第几个结点
	p = L;				//L指向头指针,头指针是第0个结点,将p指向头指针
	while(p != NULL && j<i-1)		//通过循环来找到第i-1个结点
	{
		p = p->next;
		j++;
	}
	if(p == NULL)		//p值不合法
		return false;
	if(p->next == false)//p结点后面没有结点
		return false;
	LNode *q = p->next; //定义一个指针q来指向要删除的结点
	e = q->data;		//用e来存储要删除的数据
	p->next = q->next;	//p指针指向要删除的结点的下一位,将q从链表中断开
	free(q);			//释放结点q
	return true;
}
//删除指定结点
//p结点的数据域与p结点的下一个结点交换
//p结点的指针域指向下下一个结点,并将p结点的下一个结点删除

原理:将P结点与其下一个结点进行交换,然后删除p结点的下一个结点

bool DeteleNode(LNode *p)
{
	if(p == NULL)				//p值不合法
		return false;
	LNode *q = p->next; 		//定义一个指针q来指向要删除的结点
	p->data = p->next->data;	//p指针指向要删除的结点的下一位,将q从链表中断开
	p->next = q->next;
	free(q);					//释放结点q
	return true;
}

但是这种方法存在局限性,如果要删除的结点是最后一个结点的话,不能使用该方法,只能从头结点进行查找,然后删除.
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小二康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值