⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linklist.cpp

📁 一个完善的C++链表
💻 CPP
字号:
/*-----------------------------------------------------------------------------------------------------------------
====																																								=====
====    File name           :  linklist.cpp																								=====	
====    Project name        :  Tray	   																								=====	
====    Project number      :  -																											=====
====    Creation date       :  2008 Oct.26th																						=====	
====    Author(s)           :  Raywods Zhao																							=====	
====																																								=====
====                  Copyright Raywods 2008																						=====	
--------------------------------------------------------------------------------------------------------------------*/

#include"stdafx.h"
#include"linklist.h"

void dicTerms::InitMemberVar(char *mail_id,char *byte,char *addr_from,char *addr_to,
									char *subject,char *date,char *content)
{
		char *PtrArray[]={mail_id,byte,addr_from,addr_to,subject,date,content};
	
		memset(&mMailInfo,0,sizeof(DATA_BLOCK));
		mMailInfo.DataBlockSize=0;

		int size=0;
		int BlockSize=0;

		for(int i=0;i<NUM_OF_VAR;i++)
		{
			if(PtrArray[i]==NULL)
			{
				//传入的指针为空,直接指定为空
				mMailInfo.DataBlock[i]=NULL;
				//空指针仍然写入一个空字符,作为分隔符
				size=1;
			}
			else
			{//否则,分配字符串长度+1个字节,实现C风格字串
				size=strlen(PtrArray[i])+1;
				mMailInfo.DataBlock[i]=new char[size];
				strcpy(mMailInfo.DataBlock[i],PtrArray[i]);
			}
			//计算需要从文件读取的数据块总长度
			BlockSize+=size;
		}
		//结构中数据块长度赋值
		mMailInfo.DataBlockSize=BlockSize;
}

dicTerms::~dicTerms()
{
	for(int m=0;m<NUM_OF_VAR;m++)
	{
		if(mMailInfo.DataBlock[m]!=NULL)
		{
			delete []mMailInfo.DataBlock[m];
			mMailInfo.DataBlock[m]=NULL;
		}
	}
}

//此处导入的参数node为指向"堆"中dicTerms对象的dic指针
void dicLink::AddLink(dic *node)
{
	//在“堆”中创建dicNode对象的指针
	dicNode *pNode = new dicNode(node);
	dicNode *pCur = mHead;

	//dicLink类的成员变量自加1,统计AddLink调用次数,即添加至
	//链表中的元素数量
	mMailSum++;

	//成员变量mHead为空,表明第一次添加链表对象
	if(!mHead)
	{
		mHead = pNode;
		pCur = NULL;
		pNode = NULL;
		return;
	}

	//链表中已经存储对象,将新对象附加至末尾
	for(;pCur->getNextNode()!=NULL;)
			pCur = pCur->getNextNode();

	pCur->setNextNode(pNode);
	pCur = NULL;
	pNode = NULL;
}


//注意:链表数据保存为磁盘文件时,应区分“硬盘”和“内存”的区别!
//保存时需要剥离链表结构化数据和需要保存的数据,将程序上一次
//运行时链表指针指向的地址保存为磁盘文件是毫无意义的,本例中
//使用一个自定义的结构“llD”,专门用于存储链表的“实在数据”,并
//且以一个结构为单位存储和读取数据,前提是“数据定长”
void dicLink::Save(dicLink &saveLink)
{
	FILE *fout=NULL;

	if((fout=fopen(saveLink.GetDBfileName(),"wb"))==NULL)
	{
		assert(false);
		exit(1);
	}

	//获取链表头结点指向的dic对象
	dicNode *pNode=saveLink.getHead();
	//存储链表对象使用的指针
	dic *list=NULL;

	while(pNode!=NULL)
	{
		//首先写入结构中保存的数据块长度
		fwrite(pNode->getDic()->GetDataBlockSize(),sizeof(unsigned int),1,fout);
		
		int tag=0;

		for(int i=0;i<NUM_OF_VAR;i++)
		{
			if(pNode->getDic()->GetMailInfo(i)==NULL)
				//指针为空时写入一个空字符,作为分隔符
				fwrite(&tag,1,1,fout);
			else
				fwrite(pNode->getDic()->GetMailInfo(i),sizeof(char),
				strlen(pNode->getDic()->GetMailInfo(i))+1,fout);
		}
		//指针指向下一节点
		pNode = pNode->getNextNode();
	}

	fclose(fout);
	pNode = NULL;
}


//读取磁盘文件,创建链表数据
void dicLink::Load(dicLink &loadLink)
{
	FILE *fin=NULL;
	//读取数据库二进制文件
	if((fin=fopen(GetDBfileName(),"rb"))==NULL)
	{
		assert(false);
		exit(1);
	}
	
	dic *list=NULL;
	//临时结构,用于构造DicTerms对象
	DATA_BLOCK mLoad;
	//生成的数据项目ID
	unsigned long DataID=0;
	//应该读取的数据块大小
	unsigned int length=0;

	while(true)
	{
		memset(&mLoad,0,sizeof(DATA_BLOCK));

		//首先读取文件中保存的数据块的长度
		fread(&length,sizeof(unsigned int),1,fin);
		//int length=mLoad.DataBlockSize;
		//临时变量,存储整个数据块
		char *temp=new char[length];
		char *str=new char[length];
		//将整个块读入临时变量
		fread(temp,length,1,fin);

		int PtrIndex=0;
		int StrIndex=0;
		//为结构的二维指针赋值
		for(int k=0;k<length;k++)
		{
			str[StrIndex++]=temp[k];
			//当前为一个字串段落的结尾空字符
			if(temp[k]=='\0')
			{//首字符即为空,可推断它为分隔符
				if(str[0]==0)
				{
					mLoad.DataBlock[PtrIndex]=NULL;
				}
				else
				{//否则,抽取此字串并赋值给结构的指针数组成员
					mLoad.DataBlock[PtrIndex]=new char[strlen(str)+1];
					strcpy(mLoad.DataBlock[PtrIndex],str);
					memset(str,0,length);
				}
				//索引归零,开始保存下一个字串
				StrIndex=0;
				PtrIndex++;
			}

		}
		delete []str;str=NULL;
		delete []temp;temp=NULL;

		//至此,将读取的字串添加至链表!
		list=new dicTerms(++DataID,&mLoad);
		loadLink.AddLink(list);

		//释放临时结构分配的内存
		for(int k=0;k<NUM_OF_VAR;k++)
		{
			if(mLoad.DataBlock[k]!=NULL)
			{
				delete []mLoad.DataBlock[k];
				mLoad.DataBlock[k]=NULL;
			}
		}

		//已经到达文件末尾
		if(fgetc(fin)==-1)
			break;
		//否则读取指针回退一个字符
		else
			fseek(fin,-1,SEEK_CUR);
	}
	
	fclose(fin);
	list=NULL;
}


//数据库二进制文件存在返回"真",否则返回"假"
bool dicLink::IsDBfileExist()
{
	//定义一个文件流对象,检查文件是否存在
	fstream _file(mDBfileName,ios::in);

	if(!_file)
		return false;
	
	_file.close();
	return true;
}


//通过用户指定的字串查找特定节点
dicNode *dicLink::FindLink(unsigned long MailSize)
{
	unsigned long MailByte=0;
	dicNode *pCur = mHead;
	for(unsigned long i=0;pCur!=NULL;i++)
	{
		MailByte=atoi(pCur->getDic()->GetMailInfo(BYTE));
		if(MailByte==MailSize)
			return pCur;
		pCur=pCur->getNextNode();
	}
	//经循环,pCur已为空,直接返回pCur!
	return pCur;
}


//类dicLink中此方法可能需要用于操作链表节点单元,
//因此应返回节点单元dicNode类
dicNode *dicLink::operator [](unsigned long index)
{
	dicNode *pCur = mHead;
	//链表为空或请求索引的超限
	if(!mHead||index>mMailSum)
		return NULL;

	for(unsigned long i=0;i<index-1;i++)
	{
		pCur=pCur->getNextNode();
	}

	return pCur;
}


//检查数据集是否成功载入
bool dicLink::IsDataSetNull()
{
	if(!mHead)
		return true;

	return false;
}

void dicLink::Dump()
{
	dicNode *Next = NULL;
	
	while(mHead)
	{
		Next = mHead->getNextNode();
		delete mHead;
		mHead=Next;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -