链表习题(1)

1、设计一个递归算法,删除不带头节点的单链表L中所有值为x的结点

void Del_X_3(LinkList &L,ElemType x)
	{
		LNode *p;
		if(L=null)
		return ;
		if(L->data==x)
		{
			p=L;
			L=L->next;
			free(p);
			Del_X_3(L,x);	
		}else{
			Del_X_3(L->next,x);
		}	
	} 

2、在带头结点的单链表L中,删除所有值为x的结点,并释放其空间,假设值为x的结点不唯一,试编写算法以实现上述操作
方法1

void Del_X_3(LinkList &L,ElemType x)
{
	LNode *p=L->next,*pre=L,*q;
	while(p!=null)
	{
		if(p->data==x)
		{
			q=p;
			p=p->next;
			pre->next=p;
			free(q); 
		}else{
			pre=p;
			p=p->next;
		}
	}
}

方法2

void Del_X_3(LinkList &L,ElemType x)
{
	LNode *p=L->next,*r=L,*q;
	while(p!=null)
	{
		if(p->data!=x)
		{
			r->next=p;
			r=p;
			p=p->next;
		}else{
			q=p;
			p=p->next;
			free(q);
		}
	}
} 

3、设L为带头节点的单链表,编写算法实现从尾到头反向输出每个结点的值

void R_Print(LinkList L)
	{
		if(L->next != null)
		{
			R_Print(L->next);	
		}
		printf(L->data);
	}

一、带头结点和不带头结点的区别:
1、不带头结点的单链表对于第一个节点的操作与其他节点不一样,需要特殊处理,这增加了程序的复杂性和出现bug的机会,因此,通常在单链表的开始结点之前附设一个头结点。
2、带头结点的单链表,初始时一定返回的是指向头结点的地址,所以一定要用二维指针,否则将导致内存访问失败或异常。
3、带头结点与不带头结点初始化、插入、删除、输出操作都不样,在遍历输出链表数据时,带头结点的判断条件是while(head->next!=NULL), 而不带头结点是while(head!=NULL),虽然头指针可以在初始时设定,但是如1所述,对于特殊情况如只有一个节点会出现问题。

二、头结点作用

  1. 头结点是为了操作的统一与方便而设立的,放在第一个元素结点之前,其数据域一般无意义(当然有些情况下也可存放链表的长度、用做监视哨等等)。
  2. 有了头结点后,对在第一个元素结点前插入结点和删除第一个结点,其操作与对其它结点的操作统一了。
  3. 首元结点也就是第一个元素的结点,它是头结点后边的第一个结点。头结点不是链表所必需的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值