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

📄 p384.cpp

📁 清華大學的數據結構講義,經典的書籍,照這個講義複習,一切ok
💻 CPP
字号:
#include "p382.cpp"
		int PageFind ( const TwoChars & key, const paddr PageNumber )
		//在由指针PageNumber所指的页块中搜索关键码key, 如果找到则返回1, 否则返回0。
		//因为在页块内的搜索方法一般为顺序搜索, 算法不再特别给出, 可参看程序9.1。
		{
			for (int i=0;i<PageNumber->Count;i++)
			{
				if (key==PageNumber->Names[i]) return 1;
			}
			return 0;
		};
		paddr Find ( const TwoChars & key ) {
		//在文件中搜索具有关键字key的记录。若找到, 则返回该记录所在页块的地址; 若没有找到, 则返回 0。
		   unsigned int id = makeAddress ( key, DicDepth );			//按key与DicDepth计算目录地址
		   paddr FoundPage;
		   FoundPage= Directory[id];					//在目录中找到相应页块地址
		   if ( PageFind ( key, FoundPage ) ) return FoundPage;		//在该页块中搜索, 找到返回页块地址
		   else return 0;
		}



		void DirDouble ( ) {							//目录成倍扩充的算法
		   unsigned int CurrentSize = Power2(DicDepth);
		   
		   paddr *TmpDir = Directory;				//创建临时目录		   
		   Directory = new paddr[2*CurrentSize];			//创建新目录
		   for ( int i=0; i<CurrentSize; i++ )					//从临时目录向新目录传送页块指针
			 { Directory[i] = TmpDir[i];  Directory[CurrentSize+i] = TmpDir[i]; } 
		   DicDepth++;
		   delete [] TmpDir;
		}

		int buddy ( const unsigned int index ) {
		//根据一个页块的二进制地址index计算该页块的伙伴的二进制地址, 前端的二进位是互补的。
		   if (DicDepth == 0 ) return 0;						//目录深度为0, 没有伙伴
		   if ( Directory[index]->PgDepth < DicDepth ) 			//该页块的局部深度小于目录深度
			 return -1;								//没有伙伴
		   unsigned int mask = 1;						//工作变量
		   mask <<= DicDepth - 1;						//左移DicDepth - 1位, 将1移到最高位 
		   unsigned int buddyAddress = index ^ mask;			//做异或操作, 求伙伴
		   return buddyAddress;
		}

		void ReDisTribute ( paddr PageNumber, paddr NewPage )
			//将老页块中所有关键码重新分布
		{
			int i=0;
			int CurrentSize=PageNumber->PgDepth;
			NewPage->Count=0;
			while (i<PageNumber->Count)
			{
				TwoChars key=PageNumber->Names[i];
				int NowPage=makeAddress ( key, CurrentSize );
				if (Directory[NowPage]==NewPage) 
				{
					NewPage->Names[NewPage->Count]=key;
					NewPage->Count++;

					PageNumber->Count--;
					PageNumber->Names[i]=PageNumber->Names[PageNumber->Count];
				}
				else
					i++;
			}
		}


		void Split ( const TwoChars key, paddr PageNumber ) {		//分裂页块
		   int CurrentSize = DicDepth;						//记下老的目录大小
		   if ( PageNumber->PgDepth == DicDepth )			//页块深度等于目录深度时
			 DirDouble( );							//页块分裂将导致目录成倍扩充
		   paddr NewPage = new page;						//为伙伴页块分配存储空间
		   PageNumber->PgDepth ++;						//老页块的局部深度加1
		   unsigned int id = makeAddress ( key, CurrentSize );		//按key与老DicDepth计算二进制地址
		   unsigned int bd = buddy ( id );					//找伙伴页块的二进制地址	
		   Directory [ bd ] = NewPage;						//建立伙伴页块的目录项		   
		   NewPage->PgDepth = PageNumber->PgDepth;			//伙伴的局部深度等于老页块的局部深度
		   ReDisTribute ( PageNumber, NewPage );				//将老页块中所有关键码重新分布
		} 

		int Add (const TwoChars & key ) ;

	   
		void Insert ( paddr PageNumber, const TwoChars & key ) {
		//将新关键码key插入到由PageNumber指定的页块中。
		   if ( PageNumber->Count != PageSize ) {				//若本页块中关键码个数未满
			 PageNumber->Names [ PageNumber->Count ] = key;
			 PageNumber->Count++;						//直接插入
		   }
		   else {									//否则
			 Split ( key, PageNumber );						//将页块一分为二
			 Add ( key);								//插入
		   }
		}


		int Add (const TwoChars & key ) {
		//将一个新关键码key插入到目录所指定的文件中。
		   paddr foundPage = Find ( key );					//按key在文件中搜索
		   if ( foundPage ) return 0;						//若找到, 则不插入, 返回主程序
		   Insert ( Directory[makeAddress ( key, DicDepth )], key );						//将关键码key插入foundPage页块
		   return 1;
		}

⌨️ 快捷键说明

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