C语言提高篇(六)

本文详细介绍了如何在C语言中使用结构体指针实现单链表,包括创建链表、添加节点(在尾部、头部和指定位置)、移除节点、计算节点数、查找值以及链表的基本操作,如翻转和打印。
摘要由CSDN通过智能技术生成

本文介绍C语言中结构体指针的应用,使用结构体指针来构建单链表和双链表,以及实现一些关于链表的操作接口。

单链表

链表(linked list)就 一些包含数据的独立数据结构(通常称为节点)的集合。链表中的每个节点通过链 或指针连接在一起。程序通过指针访问链表中的节点。通常节点是动态分配的,但 有时你也能看到由节点数组构建的链表。即使在这种情况下,程序也是通过指针来 遍历链表的。

在单链表中,每个节点包含一个指向链表下一节点的指针。

链表最后一个节点 的指针字段的值为NULL,提示链表后面不再有其他节点。在你找到链表的第1个节点 后,指针就可以带你访问剩余的所有节点。

为了记住链表的起始位置,可以使用一 个根指针(root pointer)。根指针指向链表的第1个节点。注意根指针只是一个指 针,它不包含任何数据。

链表由一个个节点生成。下面就需要声明一个节点:

typedef struct Node
{
	struct Node* next;
	int data;
}Listnode, *nodep;

有关于结构体的声明,上一节已经做了详细介绍。

这里利用typedef给节点的结构体取了别名 :Listnode;

给指向节点的结构体指针取了别名 nodep;

存储于每个节点的数据是一个整型值。这个链表包含三个节点。如果你从根指 针开始,随着指针到达第1个节点,你可以访问存储于那个节点的数据。随着第1个 节点的指针可以到达第2个节点,你可以访问存储在那里的数据。最后,第2个节点 的指针带你来到最后一个节点。零值提示它是一个NULL指针,在这里它表示链表中 不再有更多的节点。

创建根节点:

nodep Linklsit_Creat(void)
{
	nodep temp = NULL;
	temp = (nodep)malloc(sizeof(Listnode));
	if (temp == NULL) 
		return NULL;
	temp->data = 0;
	temp->next = NULL;
	return temp;
}

根节点不存储内容,他指向存储数据的第一个节点,根节点也可以叫头结点。

添加新节点:

在尾部添加新节点:

int LinkList_Add_Tail(nodep root, int val)
{
	if (root == NULL) return -1;

	nodep cur = root;
	while (cur->next != NULL)cur = cur->next;
	nodep new = (nodep)malloc(sizeof(Listnode));
	if (new == NULL) return 0;

	new->data = val;
	new->next = NULL;
	cur->next = new;

	return 1;

}

该函数接受两个参数,一个是根节点的指针,一个是新节点储存的数据。

返回值是错误码。

在头部添加新节点:

int LinkList_Add_Head(nodep root, int val)
{
	if (root == NULL) return -1;

	nodep new = (nodep)malloc(sizeof(Listnode));
	if (new == NULL)return 0;

	new->data = val;
	new->next = root->next;
	root->next = new;
	return 1;
}

该函数接受两个参数,一个是根节点的指针,一个是新节点储存的数据。

在根节点和第一个节点之前添加一个新节点,使之成为新的第一个节点。

在指定位置添加新节点:、

int LinkList_Add_Index(nodep root, int index,int val)
{
	if (root == NULL) return -1;

	if (index == 0) LinkList_Add_Head(root, val);

	nodep cur = root->next;
	nodep new = (nodep)malloc(sizeof(Listnode));

	if (new == NULL) return -1;
	for (int i = 1; cur != NULL; i++)
	{
		if (i == index)
		{
			new->data = val;
			new->next = cur->next;
			cur->next = new;
			return 1;
		}
		else cur = cur->next;

	}
	return 0;

}

在有序链表中插入一个新值,让其仍旧有序。

/*
** 插入到一个有序单链表。函数的参数是一个指向链表第一个节点的指针,以及一个需要插入的新值
*/
int Linklist_Insert(register nodep* rootp, int val)
{
	if (*rootp == NULL)return -1;
	nodep cur;
	nodep new;

	while ((cur = *rootp) != NULL && val > cur->data)
	{
		rootp = &cur->next;
	}

	new = (nodep)malloc(sizeof(Listnode));
	if (new == NULL) return 0;

	new->data = val;
	new->next = cur;
	*rootp = new;

	return 1;

}

移除节点:

方法一:

int Linklist_Remove_Node(nodep* rootp, nodep node)
{
	if (*rootp == NULL || node == NULL) return -1;
	nodep cur = *rootp;

	while ((cur = *rootp) != NULL && cur  != node)
	{
		rootp = &cur->next;
	}
	*rootp = node->next;
	free(node);
	return 0;

}

方法二:

int LinkList_Del_Index(nodep root, int index)
{
	if (root == NULL) return -1;
	
	if (index == 0 )
	{
		nodep temp = root->next;
		if (temp != NULL)
		{		
			root->next = temp->next;
			free(temp);
			return 1;
		}
	}

	nodep cur = root->next;
	for (int i = 1; cur != NULL && cur->next != NULL; i++)
	{
		if (i == index)
		{
			nodep temp = cur->next;
			if (temp != NULL)
			{
				cur->next = temp->next;
				free(temp);
				return 1;
			}

		}
		else cur = cur->next;
	}
	return 0;
}

计算节点数:

/*计数一个单链表的节点个数*/
int Linklist_NodeLength(nodep root)
{
	if (root == NULL) return -1;
	int length = 1;
	nodep cur = root->next;
	while ((cur=cur->next) != NULL)length++;
	return length ;
}

查找给定值:

/*在一个无序的单链表中寻找一个特定的值,并返回一个指
向该节点的指针。*/
nodep Linklist_Find_Val(nodep root, int val)
{
	if (root == NULL) return NULL;
	nodep cur = root->next;
	while (cur != NULL)
	{
		if(cur->data == val)
			return cur;
		else
			cur = cur->next;

	}
	return NULL;
}

翻转链表:

/*翻转链表,当链表被重排之后,函数返回一个指向链表
新头节点的指针*/
nodep Linklist_Reverse(nodep root)
{
	nodep temp;
	nodep pre = NULL;
	nodep cur = root;

	while (cur != NULL)
	{
		temp = cur->next;
		cur->next = pre;
		pre = cur;
		cur = temp;
	}
	return pre;
}

打印链表:

/*打印单链表*/
void Linklist_Show(nodep root)
{
	nodep cur = root;
	if (root == NULL || cur == NULL)printf("list is null\n");

	for (int i = 0; cur != NULL; i++)
	{
		printf("%d -> ",cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

以上就是单链表常见函数的实现。

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值