删除单链表中指针q指向的结点

题目:有一个非空单链表list,每个结点中存放一个整型数据。 指针q指向链表中某一个结点,编写函数delLink,删除q指向的结点。本文讨论的链表不带头结点。


链表定义如下:

typedef struct node

{

ElemType data;             //数据域

struct node *next;         //指针域

}LNode, *LinkList;


分析:要删除单链表中的结点,最重要的是获取其前驱结点的指针。但此题中只给出了要删除的结点指针q,并不知道其前驱结点的指针,因此无法直接删除q指向的结点。因此需要通过一个循环来遍历链表,找到q的前驱结点,完成删除操作。算法代码描述如下:

/*这里应该是LinkList *list,而不是LinkList list,否则下面第6行对*list的修改无法在主函数中生效(LinkList list应该也是指针,修改为什么无法在主函数生效,暂时不理解)*/
void delLink(LinkList *list, LinkList q)     
{
	LinkList r;
	if (q == *list) 
	{
		*list = q->next;			/*如果q指向的结点即为第1个结点,则需要修改list的值*/
		free(q);					/*释放被删除结点的空间*/
	} 
	else 
	{
		r = *list;
		while ((r->next != q)&&(r->next != NULL)) 
		{
			r = r->next;			/*通过循环找到q所指结点的前驱结点*/
		}

		if (r->next != NULL) 
		{
			r->next = q->next;		/*删除q所指向的结点*/
			free(q);				/*释放被删除结点的空间*/
		}
	}
}

该算法时间复杂度为O(n),算法测试用例如下:

#include <stdio.h>
#include <malloc.h>

typedef struct node
{
	int data;
	struct node *next;
}LNode,*LinkList;

LinkList GreatLinkList(int n)
{
	/*建立一个长度为n的链表*/
	LinkList p, r, list = NULL;
	int e;
	int i;
	for (i=1;i<=n;i++)
	{
		scanf("%d",&e);					/*获取链表结点中的数据元素*/
		p=(LinkList)malloc(sizeof(LNode));	/*分配一个新的链表结点*/
		p->data=e;
		p->next=NULL;
 		if (list == NULL) 
		{
				list = p;				/*list指向第一个结点,list是头指针*/
		} 
		else 
		{
				r->next = p;			/*将新结点连接到链表的尾部*/
		}
		r = p;						/*指针r始终指向链表的最后一个结点*/
	}
	return list;					/*返回链表的头指针*/
}

void delLink(LinkList *list, LinkList q) 
{
	LinkList r;
	if (q == *list) 
	{
		*list = q->next;			/*如果q指向的结点即为第1个结点,则需要修改list的值*/
		free(q);					/*释放被删除结点的空间*/
	} 
	else 
	{
		r = *list;
		while ((r->next != q)&&(r->next != NULL)) 
		{
			r = r->next;			/*通过循环找到q所指结点的前驱结点*/
		}

		if (r->next != NULL) 
		{
			r->next = q->next;		/*删除q所指向的结点*/
			free(q);				/*释放被删除结点的空间*/
		}
	}
}

void printLink(LinkList list) 
{
	while (list != NULL) 
	{
		printf("%3d",list->data);	/*打印出每个结点中的数据data*/
		list = list->next;
	}
	printf("\n");
}

main() 
{
	LinkList list, q;
	int i;
	q = list = GreatLinkList(10);	/*创建包含10个元素的单链表,并初始化该链表*/
	delLink(&list, q);				/*删除q指向的结点*/
	printLink(list);				/*打印出链表中的内容*/
	q = list;
	for (i=0; i<4; i++) 
	{
		q = q->next;				/*指针q指向链表中第5个元素*/
	}
	delLink(&list, q);				/*删除q指向的结点*/
	printLink(list);				/*打印出链表中的内容*/
	getchar();
	getchar();
}






猜你喜欢

转载自blog.csdn.net/hhhlizhao/article/details/78926823