【数据结构】单链表按位序删除结点(带头结点的和不带头结点的)和指定结点的删除

需求:删除单链表第i个位置的结点,并返回删除的结点值

  • 带头结点的
    思路:删除第i个,由于单链表不具有随机存取的特点,就要遍历整个单链表,找到位序为i-1的结点,然后改变i-1的指针指向,跳过i指向i+!,在使用free函数释放掉位序为i的结点,实现删除
bool ListDelete(LinkList &L,int i,int &e) {
	if(i<1) {
		return false;
	}
	LNode *p;
	p=L;
	int j=0;
	while(p!=NULL && j<i-1) {
		p=p->next;
		j++;
	}
	if(p=NULL) {
		return false;
	}
	LNode *q=p->next;			// p当前是i-1位置的结点,p->next指向的是i位置的结点,声明一个指针变量存储一下i位置的结点
	p->next=q->next;		// p结点指向q结点的指针域中存储的下一结点,也就是i+1位置的结点
	e=q->data;
	free(q);
	return true;
}
  • 不带头结点的
    思路:与带头结点的删除不一样的地方是,由于不带头结点,头指针L指向链表的第一个节点,当删除的位序为1时,就要改变头指针L的指向,所以要单独判断i=1时的情况,其余跟带头结点的一样
bool ListDelete_NoL(LinkList &L,int i,int &e) {
	if(i<1) {
		return false;
	}
	if(i==1) {
		LNode *q=L;		// 头指针L指向链表第一个结点,声明一个指针变量q用来存储链表的第一个结点
		L=q->next;		// q->next:q是第一个结点,那么q->next就表示q结点的指针域存储的下一结点的地址,即链表的第二个结点的地址,赋值给L,就是让头指针L指向链表的第二个结点
		free(q);		// 释放q结点,头指针L又指向原链表的第二个结点,那么就表示q结点被删,原2变成了1
	}
	LNode *p;
	p=L;
	int j=0;
	while(p!=NULL && j<i-1) {
		p=p->next;
		j++;
	}
	if(p=NULL) {
		return false;
	}
	LNode *q=p->next;		
	p->next=q->next;		
	e=q->data;
	free(q);
	return true;	
}

需求:删除指定的p节点

  • 指定节点的删除
    思路:改变p结点前面那个结点的指向,再释放p结点即可,但是怎么拿到p结点的前一结点呢:虽然拿不到前一结点的信息,但是可以操作下一结点的信息,让下一结点的值给p结点,p结点的指针域在指向下一结点的指针域存储的地址,就达到了将p结点变成p结点下一结点的目的,此时再删除p结点的下一结点,就可以实行指定结点的删除了,毕竟此时p结点的数据域和指针域都已经变成了原p结点下一结点的数据域和指针域
bool deleteNode(LNode *p, int &e) {
	if(p==NULL) {
		return false;
	}
	LNode *q=p->next;		// 声明一个指针变量用来存储p结点的下一结点
	p->next=q->next;			
	p->data=p->next->data;		// 注意:p结点的数据域想要拿到q结点的数据域,绝对不能用q->data去赋值,因为声明q的时候,q是作为指针变量去声明的,它返回的是LNode类型数据的指针,存储了一个内存地址,而没有存储数据域,所以要写出p->next->data,因为p>next表示p结点的下一结点,而p->next->data就表示p结点的下一结点的数据域
	free(q);
}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值