首页 > 其他分享 >链表的一些常用函数

链表的一些常用函数

时间:2024-08-22 14:22:52浏览次数:15  
标签:node tmp 常用 函数 mid next 链表 link first

本文用一个相同的主函数和结构体来讲述链表的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;
}

标签:node,tmp,常用,函数,mid,next,链表,link,first
From: https://blog.csdn.net/A_hard_August/article/details/141427163

相关文章

  • 数据结构链表入门指南 链表基本代码实现以及测试步骤
    链表介绍链表是一种数据结构,它由一系列节点组成,每个节点包含数据部分和指向下一个节点的指针。链表的基本特性包括:动态大小:链表的大小可以根据需要动态调整,不像数组那样需要事先定义固定大小。节点连接:每个节点通过指针连接到下一个节点,从而形成一个链状结构。灵活插入和......
  • windows常用命令
    一、CMD运行常用命令1.打开windows启动文件--C:\ProgramData\Microsoft\Windows\StartMenu\Programs\StartUpshell:startup2.防火墙高级设置fw.msc3.注册文件gpedit.msc4.磁盘管理diskmgmt.msc5.安全策略secpol.msc二、查询常用1.安装telnet客服端后,仍无法使......
  • scanf函数
    当我们有了变量,我们需要给变量输入值就可以使用scanf函数。eg:1#include<stdio.h>2intmain()3{4intscore=0;5printf("请输入成绩:");6scanf("%d\n",score);7printf("成绩是:%d\n",score);8return0;9}接下来我们介绍一下scanf函数。1.基本用法scanf()函......
  • scanf函数(4)
    3.赋值忽略符有时,用户的输入可能不符合预定的格式。1#include<stdio.h>2intmain()3{4intyear=0;5intmonth=0;6intday=0;7scanf("%d-%-d%-d",&year,&month,&day);8printf("%d%d%d\n",year,month,day);9return0;10}上面示例中,如果用户......
  • scanf函数(2)
    1.scanf函数的基本用法scanf函数处理用户输入的原理是,用户的输入先放入缓存,等到按下回车键后按照占位符对缓存进行解读。解读用户输入时,会从上次解读遗留的第一个字符开始,直到读完缓存,或遇到第一个不符合条件的字符为止。1#include<stdio.h>2intmain()3{4intx;5......
  • apk机器(手机,打卡机,录像机)连接电脑 常用adb操作命令
    adb简介adb的全称为AndroidDebugBridge,就是起到调试桥的作用。它就是一个命令行窗口,用于通过电脑端与模拟器或者是设备之间的交互。借助adb工具,我们可以管理设备的状态。还可以进行很多手机操作,如安装软件、系统升级、运行shell命令等等。其实简而言说,adb就是连接Android与PC......
  • Python之列表的常用方法(添加删除排序等)
    一、列表的可变性二、列表方法1、不修改列表的方法2、修改列表的方法(1)添加(2)删除(3)列表排序(4)颠倒列表三、练习四、range、split和多重赋值五、使用join在列表和字符串之间转换一、列表的可变性在字符串中,不能直接去替换字符串中指定索引的值,需要使用切片和连接符。......
  • 关于C++函数返回值的拷贝优化问题
    在传统C++程序中,如果函数的返回值是一个对象的话,可能需要对函数中的局部对象进行拷贝。如果该对象很大的话,则程序的效率会降低。在C++11以后,出现的移动语义(MoveSemantic)及拷贝优化(CopyElision)都是解决这个问题的方法。本文试图以一个最简单的例子来说明这个问题。案例下面来看......
  • java创建链表异常解决
    问题解决问题解释该错误表明,在试图创建非静态类实例时,没有正确引用外部类的实例。源代码如下packagevjudge;importjava.util.Scanner;publicclasstest{//节点类publicclassNode{intdata;Nodenext;Node(intdata){......
  • Python中的常用的数据预处理所需工具
    Jupyter对于数据预处理的重要功能是支持用逐行编写和运行代码,实时查看结果。Jupyter是一个开源的交互式计算环境,它允许用户以网页的形式编写和运行代码,以及创建和共享文档,这些文档可以包含实时代码、方程、可视化和解释性文本。Jupyter的主要组件包括:1.JupyterNotebook:一......