链表基础(包含头插法尾插法)

单链表基础(包含头尾插法)

**一 .单链表的概念 **
1. 单链表的构成

单链表是由若干个结构体构成的,每个结构体都包含数据域和指针域,有前驱结构体的结构体的指针域里都存着下一个结构体的地址,第一个结构体(也叫头节点)没有前驱结构体。
就像下图一样:请添加图片描述

2.单链表的操作

先命名一个head结构体,再用malloc函数为它申请一块空间,再利用循环命名所需要的结构体个数并利用malloc 函数申请空间,依次让结构体的指针域指向下一个结构体的所在位置。就像下面的代码:

typedef struct Node{
int num;
struct Node* next;
}node;
node* head,*p;  //定义头节点
head=(node*)malloc(sizeof(node));
for(i=0;i<5;i++)
{
	p=(node*)malloc(sizeof(node));  //循环创建子结构体
}

3.单链表与数组的区别

数组是一块连续分配的空间,每个数据都是紧密排列的(也就是一个挨一个),而单链表则是任意空间,你根本不清楚每个结构体的具体位置,它们是依靠结构体里的指针域来连接的,就像下图一样

二. 创建链表

首先,一个单链表需要一个头节点(里面的数据域为NULL),我就以要创建一个简单的学生管理来举例,里面数据域包含学生的学号,名字。请看以下代码:
(这个为尾插法,也是比较常用的)

#include<stdio.h>
#include<stdlib.h>
typedef  struct Student{            
int no;
char name[10];
struct Student*  next;
}student;
int mian()
{
	student *head,*p,*tail;      //tail为尾指针
	head=(student*)malloc(sizeof(student));
	head->next=NULL;
	tail=head;
	int no,n;
	char name[10];
	printf(" 输入学生的个数:");
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		p=(student*)malloc(sizeof(student));
		printf("输入%d个学生的学号:",i+1);
		scanf("%d",&no);
		p->no=no;
		printf("输入%d个学生的 名字:",i+1);
		scanf("%s",name);
		strcpy(p->name,name)
		tail->next=p;
		tail=p;
}

以下为头插法

#include<stdio.h>
#include<stdlib.h>
typedef  struct Student{            
int no;
char name[10];
struct Student*  next;
}student;
int mian()
{
	student *head,*p;
	head=(student*)malloc(sizeof(student));
	head->next=NULL;
	tail=head;
	int no,n;
	char name[10];
	printf(" 输入学生的个数:");
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		p=(student*)malloc(sizeof(student));
		printf("输入%d个学生的学号:",i+1);
		scanf("%d",&no);
		p->no=no;
		printf("输入%d个学生的 名字:",i+1);
		scanf("%s",name);
		strcpy(p->name,name);
		p->next=head->next;
		head->next=p;
}

****** 头插法和尾插法的区别

头插法插入的数据为倒置的,往往与自己想要的顺序相反,
而尾插法与自己输入的顺序相同,所以一般都是选举尾插法。

三.链表的插入

首先,要往链表中插入一个结构体(假设为student p),就要先知道想要插入的位置,然后定义一个student q, 先让student q指到要插入位置的前一个位置
再让student p的指针域指向student q指针域指向的地方,student q的指针域指向p,这样文字描述可能太混乱了,看下面的代码(以下代码为一个子函数,返回的是一个student
型的值,并且在主函数里是由head来接受这个值的),假设在主函数里链表已经创建好了,并且在主函数里还输入好了这个学生的信息,有studentp保存着,要插入的位置设为cnt

student*  insertlist (student* head,student*p,int cnt)
{
	student *q=head;
	int count=0;
	while(count<cnt-1&&q!=NULL)
	{
		q=q->next;
		count++;
	}
	p->next=q->next;
	q->next=p;
	return head;
}

四.链表的删除

  1. 链表的删除需要两个student* 类型的变量,并且一定是一前一后的关系(先让前面那个变量在头节点那个位置,后面那个变量在头节点下一个位置,并且两个变量一起移动,这样就永远都是一前一后了),在前面的变量是为了方便把链表重新连接起来,而后面的变量是用来指定到要删除的位置的,要实现删除,首先要知道删除的是哪个位置,在学生管理系统中我就用学号作为代表( 在主函数中设为No),同样的,链表的删除也用一个子函数来写,并且返回值也是一个student* 型的值,也同样用head 来连接
student* deletelist(student* head,int No)
{
	student *p,*q;
	p=head;
	q=head->next;
	while(q)
	{
		if(q->next==No)
		{
			p->next=q->next;
			free(q);
		}
		else
		{
			p=q;
			q=q->next;
		}
	}
	return head;
}

五.链表的遍历

链表的遍历就是把输入的内容全部输出一遍,同样的,也是设为子函数的形式。遍历是从head节点开始遍历的并且不需要返回值,显然这需要用循环来遍历, 并且我们这遍历出来的值是学号(如果想输出其他的值只需要改变输出的变量即可)。先设一个与head变量类型相同的变量,让它指向 head->next指向的地方,并在没一轮循环之后让这个变量指向它指针域指向的地方,也就是它的下一个节点,当这个变量为空时,说明已经遍历完成了,所以我们这里用while循环比较合适

void putlist(student *head)
{
	student* q=head->next;
	while(q)
	{
		printf("%d",q->no);
		q=q->next;
	}
}
使用优化算法,以优化VMD算法的惩罚因子惩罚因子 (α) 和分解层数 (K)。 1、将量子粒子群优化(QPSO)算法与变分模态分解(VMD)算法结合 VMD算法背景: VMD算法是一种自适应信号分解算法,主要用于分解信号为不同频率带宽的模态。 VMD的关键参数包括: 惩罚因子 α:控制带宽的限制。 分解层数 K:决定分解出的模态数。 QPSO算法背景: 量子粒子群优化(QPSO)是一种基于粒子群优化(PSO)的一种改进算法,通过量子行为模型增强全局搜索能力。 QPSO通过粒子的量子行为使其在搜索空间中不受位置限制,从而提高算法的收敛速度与全局优化能力。 任务: 使用QPSO优化VMD中的惩罚因子 α 和分解层数 K,以获得信号分解的最佳效果。 计划: 定义适应度函数:适应度函数根据VMD分解的效果来定义,通常使用重构信号的误差(例如均方误差、交叉熵等)来衡量分解的质量。 初始化QPSO粒子:定义粒子的位置和速度,表示 α 和 K 两个参数。初始化时需要在一个合理的范围内为每个粒子分配初始位置。 执行VMD分解:对每一组 α 和 K 参数,运行VMD算法分解信号。 更新QPSO粒子:使用QPSO算法更新粒子的状态,根据适应度函数调整粒子的搜索方向和位置。 迭代求解:重复QPSO的粒子更新步骤,直到满足终止条件(如适应度函数达到设定阈值,或最大迭代次数)。 输出优化结果:最终,QPSO算法会返回一个优化的 α 和 K,从而使VMD分解效果最佳。 2、将极光粒子(PLO)算法与变分模态分解(VMD)算法结合 PLO的优点与适用性 强大的全局搜索能力:PLO通过模拟极光粒子的运动,能够更高效地探索复杂的多峰优化问题,避免陷入局部最优。 鲁棒性强:PLO在面对高维、多模态问题时有较好的适应性,因此适合海上风电时间序列这种非线性、多噪声的数据。 应用场景:PLO适合用于优化VMD参数(α 和 K),并将其用于风电时间序列的预测任务。 进一步优化的建议 a. 实现更细致的PLO更新策略,优化极光粒子的运动模型。 b. 将PLO优化后的VMD应用于真实的海上风电数据,结合LSTM或XGBoost等模型进行风电功率预测。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值