双链表操作

//------------------------------------------------------------------------------
// 双链表的相关操作
//------------------------------------------------------------------------------
#include <iostream>
using namespace std;

// 双链表数据结构
typedef struct DNode
{
	int data;
	DNode* prev;
	DNode* next;

}DoubleList, *pDoubleList;

//******************************************************************************
// Name: CreateNode
// Desc: 创建双链表
//******************************************************************************
DNode* CreateDNode()
{
	DNode* head;
	DNode* tempPrev;
	DNode* tempNext;
	head = new DNode;
	head->next = NULL;
	head->prev = NULL;
	tempPrev   = NULL;
	tempNext   = head;

	cout<<"please input some datas to create a doubleNode:"<<endl;
	int data;
	while(cin>>data)
	{
		// 赋值后继
		tempNext->next = new DNode;
		tempNext	  = tempNext->next;
		tempNext->data = data;

		// 赋值前驱
		tempNext->next = NULL;
		tempNext->prev = tempPrev;
		tempPrev      = tempNext;
	}

	head = head->next;
	head->prev = NULL;

	return head;

}

//******************************************************************************
// Name: DNodeLength
// Desc: 计算双链表的长度
//******************************************************************************
int DNodeLength(DNode* head)
{
	if(head == NULL) return 0;

	DNode* currentDNode = head;
	int	   currentLength = 0;
	while(currentDNode != NULL)
	{
		++currentLength;
		currentDNode = currentDNode->next;
	}

	return currentLength;
}

//******************************************************************************
// Name: PrintDNode
// Desc: 打印双链表
//******************************************************************************
void PrintDNode(DNode* head)
{
	if(head == NULL)	
	{
		cout<<"链表元素为空"<<endl;
	}
	else
	{
		DNode* currentDNode = head;
		while(currentDNode != NULL)
		{
			cout<<currentDNode->data<<" ";
			currentDNode = currentDNode->next;
		}
		cout<<endl;
	}
}

//******************************************************************************
// Name: 删除双链表中的元素
// Desc: DeleteDNode(DNode* head, int data)
//******************************************************************************
DNode* DeleteDNode(DNode* head, int data)
{
	if(head == NULL) 
	{
		cout<<"链表为空!"<<endl;
		return NULL;
	}
	else
	{
		DNode* currentNode = head;

		// 试图找到要删除的元素
		while(currentNode != NULL 
			&& currentNode->data != data)
		{	
			currentNode = currentNode->next;
		}

		if(currentNode->prev != NULL)			// 有前驱
		{
			if(currentNode->next != NULL)		// 有前驱,有后继,删除中间元素
			{
				currentNode->prev->next = currentNode->next;
				currentNode->next->prev = currentNode->prev;
			}
			else								// 有前驱,无后继,删除最后一个元素
			{
				currentNode->prev->next = NULL;
				currentNode->prev = NULL;
			}
		}
		else									// 无前驱
		{
			if(currentNode->next != NULL)		// 无前驱,有后继,删除第一个元素
			{
				head = head->next;				// 改变了头指针地址
				currentNode->next->prev = NULL;
			}
			else								// 无前驱,无后继,删除唯一元素
			{
				head = NULL;					// 此处不能进行delete head操作,因为下面会删除,删除两次会有问题
			}
		}

		delete currentNode;
		currentNode = NULL;

		return head;
	}
}

//******************************************************************************
// Name: InsertDNode
// Desc: 双链表中插入元素,参数为位置和要插入的值
//******************************************************************************
DNode* InsertDNode(DNode* head, int pos, int data)
{
	DNode* newDNode   = new DNode;		        // 待插入的新节点
	newDNode->data = data;
	newDNode->next = NULL;
	newDNode->prev = NULL;

	DNode* rightDNode = head;                   // 将在这个位置的前面插入
	int	   maxPos	  = DNodeLength(head)    ;  // 双链表长度

	if(head == NULL)	
	{
		return newDNode;
	}

	if(pos > maxPos)						  // 如果越界,则插在最尾部
	{
		pos = maxPos ;
	}


	for(int i = 1; i < pos; ++i)
	{
		rightDNode = rightDNode->next;
	}

	if(0 == pos || maxPos == pos)			 // 插在头部和插在尾部的单独处理
	{
		if(pos > 0)							 // 尾部
		{
			rightDNode->next = newDNode;
			newDNode->prev = rightDNode;
			newDNode->next = NULL;
		}
		else								 // 头部
		{
			newDNode->next = rightDNode;
			newDNode->prev = NULL;
			rightDNode->prev = newDNode;
			head = newDNode;				// 改变了头指针地址
		}
	}
	else									 // 插在中间的元素
	{
		rightDNode->prev->next = newDNode;
		newDNode->prev = rightDNode->prev;

		rightDNode->prev = newDNode;
		newDNode->next = rightDNode;
	}

	return head;
}


int main()
{
	int deleteElem;		// 要删除的元素
	int addPos;			// 插入的位置
	int addElem;		// 添加的元素

	cout<<"创建双链表:"<<endl;
	DNode* head = CreateDNode();
	cout<<"--------------------------------------------------------"<<endl;
	cout<<"双链表长度为: "<<DNodeLength(head)<<endl;
	cout<<"--------------------------------------------------------"<<endl;
	cout<<"打印双链表: "<<endl;
	PrintDNode(head);
	cout<<"--------------------------------------------------------"<<endl;

	cout<<"请输入要删除的元素:"<<endl;
	cin.clear();		// 创建双链表的时候,已经暂用了IO缓冲
	cin>>deleteElem;
	head = DeleteDNode(head, deleteElem);
	cout<<"--------------------------------------------------------"<<endl;
	cout<<"打印双链表: "<<endl;
	PrintDNode(head);
	cout<<"--------------------------------------------------------"<<endl;
	
	cout<<"请输入插入元素的位置和要插入的元素"<<endl;
	cin>>addPos>>addElem;
	head = InsertDNode(head, addPos, addElem);
	cout<<"--------------------------------------------------------"<<endl;
	cout<<"打印双链表: "<<endl;
	PrintDNode(head);
	cout<<"--------------------------------------------------------"<<endl;

	system("pause");
	return 0;
}


内容概要:本文详细介绍了扫描单分子定位显微镜(scanSMLM)技术及其在三维超分辨体积成像中的应用。scanSMLM通过电调透镜(ETL)实现快速轴向扫描,结合4f检测系统将不同焦平面的荧光信号聚焦到固定成像面,从而实现快速、大视场的三维超分辨成像。文章不仅涵盖了系统硬件的设计与实现,还提供了详细的软件代码实现,包括ETL控制、3D样本模拟、体积扫描、单分子定位、3D重建和分子聚类分析等功能。此外,文章还比较了循环扫描与常规扫描模式,展示了前者在光漂白效应上的优势,并通过荧光珠校准、肌动蛋白丝、线粒体网络和流感A病毒血凝素(HA)蛋白聚类的三维成像实验,验证了系统的性能和应用潜力。最后,文章深入探讨了HA蛋白聚类与病毒感染的关系,模拟了24小时内HA聚类的动态变化,提供了从分子到细胞尺度的多尺度分析能力。 适合人群:具备生物学、物理学或工程学背景,对超分辨显微成像技术感兴趣的科研人员,尤其是从事细胞生物学、病毒学或光学成像研究的科学家和技术人员。 使用场景及目标:①理解和掌握scanSMLM技术的工作原理及其在三维超分辨成像中的应用;②学习如何通过Python代码实现完整的scanSMLM系统,包括硬件控制、图像采集、3D重建和数据分析;③应用于单分子水平研究细胞内结构和动态过程,如病毒入侵机制、蛋白质聚类等。 其他说明:本文提供的代码不仅实现了scanSMLM系统的完整工作流程,还涵盖了多种超分辨成像技术的模拟和比较,如STED、GSDIM等。此外,文章还强调了系统在硬件改动小、成像速度快等方面的优势,为研究人员提供了从理论到实践的全面指导。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值