链表的一些常用函数

本文用一个相同的主函数和结构体来讲述链表的14种常见函数

主函数和结构体

#include<stdio.h>
#include<stdlib.h>
typedef struct node 
{
	int num;
	struct node* p_next;
}node;
typedef struct 
{
	node head;
	node tail;
}link;


int main()
{
	link lnk = { 0 };
	link_init(&lnk);
	link_add_head(&lnk, 20);
	link_add_head(&lnk, 10);
	link_append(&lnk, 90);
	link_append(&lnk, 100);
	link_insert(&lnk, 70);
	link_insert(&lnk, 40);
	link_insert(&lnk, 60);
	link_insert(&lnk, 30);
	link_insert(&lnk, 50);
	link_insert(&lnk, 80);
	link_remove_head(&lnk);
	link_remove_tail(&lnk);
	int val = 0;
	link_get_head(&lnk, &val);
	printf("最前面数字是%d\n", val);
	link_get_tail(&lnk, &val);
	printf("最后面数字是%d\n", val);
	int size = link_size(&lnk);
	for (int num = 0; num < size; num++) 
	{
		link_get(&lnk, &val, num);
		printf("%d ", val);
	}
	link_deinit(&lnk);
	return 0;
}

链表的初始化函数



//链表的初始化函数
void link_init(link* p_link) 
{
	p_link->head.p_next = &(p_link->tail);
	p_link->tail.p_next = NULL;
}

链表的清理函数

//链表的清理函数
void link_deinit(link* p_link) 
{
	while (p_link->head.p_next != &(p_link->tail)) 
	{
		node* p_first = &(p_link->head);
		node* p_mid = p_first->p_next;
		node* p_last = p_mid->p_next;
		p_first->p_next = p_last;
		free(p_mid);
		p_mid = NULL;
	}
}

统计有效数字个数的函数

//统计有效数字个数的函数
int link_size(const link* p_link)
{
	int cnt = 0;
	const node* p_node = NULL;
	for (p_node = &(p_link->head); p_node != &(p_link->tail); p_node =p_node->p_next) 
	{
		const node* p_first = p_node;
		const node* p_mid = p_first->p_next;
		const node* p_last = p_mid->p_next;
		if (p_mid != &(p_link->tail)) 
		{
			cnt++;
		}
	}
	return cnt;
	// }
	// return cnt-1;
}

判断链表是否为空的函数

//判断链表是否为空的函数
int link_empty(const link* p_link) 
{
	return p_link->head.p_next == &(p_link->tail);
}

判断链表是否为满的函数

//判断链表是否为满的函数
int link_full(const link* p_link) 
{
	return 0;
}

在最前面插入新节点的函数

//在最前面插入新节点的函数
int link_add_head(link* p_link, int num) 
{
	node* p_first = NULL, * p_mid = NULL, * p_last = NULL;
	node* p_node = (node*)malloc(sizeof(node));
	if (!p_node) 
	{
		return 0;
	}

	p_node->num = num;
	p_node->p_next = NULL;
	p_first = &(p_link->head);
	p_mid = p_first->p_next;
	p_last = p_mid->p_next;
	p_first->p_next = p_node;
	p_node->p_next = p_mid;
	return 1;
}

在最后加入新节点的函数

//在最后加入新节点的函数
int link_append(link* p_link, int num) 
{
	node* p_tmp = NULL;
	node* p_node = (node*)malloc(sizeof(node));
	if (!p_node) 
	{
		return 0;
	}
	p_node->num = num;
	p_node->p_next = NULL;
	for (p_tmp = &(p_link->head); p_tmp != &(p_link->tail); p_tmp = p_tmp->p_next)
	{
		node* p_first = p_tmp;
		node* p_mid = p_first->p_next;
		node* p_last = p_mid->p_next;
		if (p_mid == &(p_link->tail)) 
		{
			p_first->p_next = p_node;
			p_node->p_next = p_mid;
			break;
		}
	}
	return 1;
}

按照从小到大的顺序把新节点插入到链式物理结构中

//按照从小到大的顺序把新节点插入到链式物理结构中
int link_insert(link* p_link, int num) {
	node* p_tmp = NULL;
	node* p_node = (node*)malloc(sizeof(node));
	if (!p_node) {
		return 0;
	}
	p_node->num = num;
	p_node->p_next = NULL;
	for (p_tmp = &(p_link->head); p_tmp != &(p_link->tail); p_tmp = p_tmp->p_next) 
	{
		node* p_first = p_tmp;
		node* p_mid = p_first->p_next;
		node* p_last = p_mid->p_next;
		if (p_mid == &(p_link->tail) || p_mid->num > p_node->num)
		{
			p_first->p_next = p_node;
			p_node->p_next = p_mid;
			break;
		}
	}
	return 1;
}

删除第一个有效节点的函数

//删除第一个有效节点的函数
int link_remove_head(link* p_link) 
{
	node* p_first = NULL, * p_mid = NULL, * p_last = NULL;
	if (p_link->head.p_next == &(p_link->tail)) 
	{
		return 0;
	}
	p_first = &(p_link->head);
	p_mid = p_first->p_next;
	p_last = p_mid->p_next;
	p_first->p_next = p_last;
	free(p_mid);
	p_mid = NULL;
	return 1;
}

删除最后一个有效节点的函数

//删除最后一个有效节点的函数
int link_remove_tail(link* p_link) 
{
	node* p_tmp = NULL;
	for (p_tmp = &(p_link->head); p_tmp != &(p_link->tail); p_tmp = p_tmp->p_next) 
	{
		node* p_first = p_tmp;
		node* p_mid = p_first->p_next;
		node* p_last = p_mid->p_next;
		if (p_last == &(p_link->tail)) 
		{
			p_first->p_next = p_last;
			free(p_mid);
			p_mid = NULL;
			return 1;
		}
	}
	return 0;
}

删除某个数字所在节点的函数

//删除某个数字所在节点的函数
int link_remove(link* p_link, int num) 
{
	node* p_tmp = NULL;
	for (p_tmp = &(p_link->head); p_tmp != &(p_link->tail); p_tmp = p_tmp->p_next) 
	{
		node* p_first = p_tmp;
		node* p_mid = p_first->p_next;
		node* p_last = p_mid->p_next;
		if (p_mid != &(p_link->tail) && p_mid->num == num) 
		{
			p_first->p_next = p_last;
			free(p_mid);
			p_mid = NULL;
			return 1;
		}
	}
	return 0;
}

获得第一个有效数字的函数

//获得第一个有效数字的函数
int link_get_head(const link* p_link, int* p_num) 
{
	if (p_link->head.p_next == &(p_link->tail)) 
	{
		return 0;
	}
	const node* p_first = &(p_link->head);
	const node* p_mid = p_first->p_next;
	const node* p_last = p_mid->p_next;
	*p_num = p_mid->num;
	return 1;
}

获得最后一个有效数字的函数

//获得最后一个有效数字的函数
int link_get_tail(const link* p_link, int* p_num) 
{
	const node* p_tmp = NULL;
	for (p_tmp = &(p_link->head); p_tmp != &(p_link->tail); p_tmp = p_tmp->p_next) 
	{
		const node* p_first = p_tmp;
		const node* p_mid = p_first->p_next;
		const node* p_last = p_mid->p_next;
		if (p_last == &(p_link->tail)) 
		{
			*p_num = p_mid->num;
			return 1;
		}
	}
	return 0;
}

获得编号对应数字的函数

//获得编号对应数字的函数
int link_get(const link* p_link, int* p_num, int num)
{
	const node* p_tmp = NULL;
	int cnt = 0;
	for (p_tmp = &(p_link->head); p_tmp != &(p_link->tail); p_tmp = p_tmp->p_next) 
	{
		const node* p_first = p_tmp;
		const node* p_mid = p_first->p_next;
		const node* p_last = p_mid->p_next;
		if (p_mid != &(p_link->tail) && cnt == num) 
		{
			*p_num = p_mid->num;
			return 1;
		}
		cnt++;
	}
	return 0;
}

### C++ 中链表相关的常用函数 在 C++ 编程中,链表是一种常见的动态数据结构。标准模板库 (STL) 提供了一个名为 `std::list` 的容器来实现双向链表功能[^3]。以下是关于链表的一些常见操作及其对应的函数: #### 1. 构造与初始化 - **默认构造函数**: 创建一个空的链表。 ```cpp std::list<int> myList; ``` - **指定大小的构造函数**: 初始化具有特定数量元素的链表。 ```cpp std::list<int> myList(5, 0); // 初始有五个值为0的元素 ``` #### 2. 插入操作 - **push_back()**: 向链表尾部添加一个新元素。 ```cpp myList.push_back(10); ``` - **push_front()**: 向链表头部添加一个新元素。 ```cpp myList.push_front(20); ``` - **insert()**: 在指定位置插入一个或多个元素。 ```cpp auto it = myList.begin(); ++it; // 移动迭代器指向第二个元素的位置 myList.insert(it, 15); // 在第二个元素前插入15 ``` #### 3. 删除操作 - **pop_back()**: 删除链表中的最后一个元素。 ```cpp myList.pop_back(); ``` - **pop_front()**: 删除链表的第一个元素。 ```cpp myList.pop_front(); ``` - **erase()**: 删除由迭代器指定的一个或多个元素。 ```cpp myList.erase(myList.begin()); // 删除第一个元素 ``` #### 4. 访问元素 由于链表不支持随机访问,因此主要依赖于迭代器来进行元素的遍历。 - **begin()/end()**: 返回指向链表起始和结束位置的迭代器。 ```cpp for(auto it = myList.begin(); it != myList.end(); ++it){ cout << *it << " "; } ``` #### 5. 大小与容量 - **size()**: 获取当前链表中存储的有效元素数目。 ```cpp size_t sz = myList.size(); ``` - **empty()**: 检查链表是否为空。 ```cpp if(myList.empty()) { /* ... */ } ``` #### 6. 反转与排序 - **reverse()**: 将链表内的顺序反转。 ```cpp myList.reverse(); ``` - **sort()**: 对链表进行排序,默认升序排列。 ```cpp myList.sort(); ``` 以上列举的是基于 STL 容器 `std::list` 的一些基本方法,在实际开发过程中非常实用。如果需要手动实现链表,则需自行设计节点结构以及上述类似的接口逻辑[^2]。 ```cpp struct Node { int data; Node* next; Node(int val): data(val), next(nullptr){} }; class LinkedList{ private: Node* head; public: void pushFront(int value){/*...*/} void popFront(){/*...*/} }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值