بســم الله الـرحمــن الرحيــم
،،السلام عليكــم ورحمـة الله وبركاتــه
الحمدلله والصلاة والسلام على رسول الله وعلى آله وصحبه أجمعين
كيف حالكم إن شاء الله دائمــاً بخير ؟ :lol:
أما بعد وحتى لاأطيل على حضراتكم فقد وقعت فى ورطة ومشكلة كبير من حوالى أسبوعين وهى عبارة عن برنامج كبير خاص بال B-tree
وهو موضوع كبير وشاق فأخذت أبحث وأسأل حتى وصلت إلى حل ولكن هناك بعض العقبات فى تنفيذ الكود ولا أدرى ما المشكلة أعذرونى أنا قليل الخبرة بالبرمجة ولكن هذا ما قدرنى عليه ربى والكود كالتالى وأرجو الرد والمشاركة ليستفيد الجميع ودعواتكم بكل إخلاص لله عز وجل وبظهر الغيب أن ييسر علينا ويشرح لنا صدورنا فى هذا المجال العملاق والرهييييب وأن يغفر لنا ويرحمنا ويصرف عنا الفتن وينصرنا على أنفسنا وأعدائنا أنا وجميع إخوانى المسلمين السنة فى كل بقاع الأرض
أولا شرح ماذا يريد البرنامج
اقتباسUse a binary tree to index the previous file.
Class tree
1) Build >> make empty tree
2) Insert >> add to an existing tree
3) Search >> (key)
4) Delete
5) Display
.
.
.
.
You are supposed to take data from the file , put it in a tree
That’s everything….
Some points seems missed or incomplete,However That’s every thing was said in lectures….
أما الكود فقد قسمته إلى هيدرز كالتالى:عبارة عن كلاسين وكل كلاس له 2هيدرز واحد للتعريف والآخر للتنفيذ
#include <stdlib.h>
//Btnode definition
template <class keyType>
class BTreeNode<keyType> : public SimpleIndex <keyType>
//this is the in-memory version of the BTreeNode
{
protected :
int NextNode;
int RecAddr;
int Minkeys;
int MaxBkeys;
int Init();
void Clear(){Numkeys= 0; RecAddr= -1;}
friend class BTree <keyType>;
public :
BTreeNode (int maxkeys , int unique =1);
~BTreeNode();
//Insert and Remove return
//0 for failure
//-1 for overflow
//1 for success
int Insert (const keyType key , int recAddr);
int Remove (const keyType key , int recAddr = -1);
//int search(const keyType key) const;
void Print (ostream &) const;
int Largestkey(); //returns value of largest key
int Split (BTreeNode <keyType> * newNode); //move into newNode
int Merge (BTreeNode <keyType> * fromNode);//move from fromNode
int Updatekey (keyType oldkey , keyType newkey , int recAddr=-1);
int Pack (IOBuffer& buffer) const;
int Unpack (IOBuffer& buffer);
static int InitBuffer (FixedFieldBuffer& buffer ,
int maxkeys , int keySize = sizeof(keyType));
};
[/code1]
and this is implementation of class
#include <iostream.h>
#include <iomanip.h>
#include "Btnode definition.h"
//Implementation of class member functions
template <class keyType>
BTreeNode<keyType> :: BTreeNode(int maxkeys , int unique):
SimpleIndex<keyType> (maxkeys+1, unique)
{Init ();}
//---------------------------------------------------------
template <class keyType>
BTreeNode<keyType> :: ~BTreeNode()
{};
//----------------------------------------------------------
template <class keyType>
int BTreeNode<keyType> :: Insert (const keyType key, int recAddr)
{
int result;
result = SimpleIndex<keyType> :: Insert(key, recAddr);
if(!result)
return 0; //insert failed
if(Numkeys >= Maxkeys)
return -1; //node overflow
return 1;
}
//--------------------------------------------------------------
template <class keyType>
int BTreeNode<keyType> :: Remove (const keyType key, int recAddr)
{
int result;
result = SimpleIndex<keyType> :: Remove (key, recAddr);
if(!result)
return 0; //remove failed
if(Numkeys < Minkeys)
return -1; //node underflow
return 1;
}
//--------------------------------------------------------------
template <class keyType>
void BTreeNode<keyType> :: Print (ostream& stream) const
{
SimpleIndex<keyType> :: Print(cout);
}
//--------------------------------------------------------------
template <class keyType>
int BTreeNode <keyType> :: Largestkey ()
//returns value of largest key
{
if(Numkeys > 0)
return keys[Numkeys-1];
else
return keys[0];
}
//--------------------------------------------------------------
template <class keyType>
int BTreeNode<keyType> :: Split (BTreeNode<keyType> * newNode)
{
//check for sufficient number of keys
if(Numkeys < Maxkeys)
return 0;
//find the first key to be moved into the new node
int midpt = (Numkeys+1)/2;
int numNewkeys = Numkeys - midpt;
//check that number of keys for newNode is ok
if(numNewkeys > newNode->MaxBkeys || numNewkeys < newNode->Minkeys)
return 0;
//move the keys and recaddrs from this to newNode
for(int i=midpt; i<Numkeys; i++)
{
newNode->keys[i-midpt] = keys;
newNode->RecAddrs[i-midpt] = RecAddrs;
}
//set number of keys in the two nodes
newNode->Numkeys = numNewkeys;
Numkeys = midpt;
return 1;
}
//-----------------------------------------------------------
template <class keyType>
int BTreeNode<keyType> :: Merge (BTreeNode<keyType> * fromNode)
{
//check for too many keys
if(Numkeys+fromNode->Numkeys > Maxkeys-1)
return 0;
//move keys and recaddrs from fromNode to this
for(int i=0; i<fromNode->Numkeys; i++)
{
keys[Numkeys+i] = fromNode->keys;
RecAddrs[Numkeys+i] = fromNode->RecAddrs;
}
//adjust number of keys
Numkeys += fromNode->Numkeys;
return 1;
}
//--------------------------------------------------------------
template <class keyType>
int BTree<keyType> :: Updatekey (keyType oldkey, keyType newkey, int recAddr)
{
//look for the old key
int recAddr = Search (oldkey, recAddr);
if(recAddr < 0)
return 0; //key and recaddr not found
Remove (oldkey, recAddr);
Insert (newkey, recaddr);
return 1;
}
//-----------------------------------------------------------
template <class keyType>
int BTreeNode<keyType> :: Init () //for initialization values
{
NextNode = -1;
RecAddr = -1;
MaxBkeys = Maxkeys - 1;
Minkeys = MaxBkeys / 2;
return 1;
}
//-----------------------------------------------------------
template <class keyType>
BTreeNode<keyType> * CreateBTreeNode (int maxkeys, int unique)
{
return new BTreeNode<keyType> (maxkeys, unique);
}
//----------------------------------------------------------
template <class keyType>
int BTreeNode<keyType> :: Pack (IOBuffer& buffer) const
{
int result;
buffer.Clear ();
result = buffer.Pack (&Numkeys);
for(int i =0; i <Numkeys; i++)
{
//note only pack the actual keys and recaddrs
result = result && buffer.Pack (&keys);
result = result && buffer.Pack (&RecAddrs);
}
return result;
}
//----------------------------------------------------------
template <class keyType>
int BTreeNode<keyType> :: Unpack (IOBuffer& buffer)
{
int result;
result = buffer.Unpack (&Numkeys);
for (int i =0; i<Numkeys; i++)
{
//note only pack the actual keys and recaddrs
result = result && buffer.Unpack (&keys);
result = result && buffer.Unpack (&RecAddrs);
}
return result;
}
//------------------------------------------------------------
template <class keyType>
int BTreeNode<keyType> :: InitBuffer
(FixedFieldBuffer & buffer, int maxkeys, int keySize)
{
//initialize a buffer for the btree node
buffer.AddField(sizeof(int));
for(int i =0; i<maxkeys; i++)
{
buffer.AddField (keysize);
buffer.AddField (sizeof(int));
}
return 1;
}and the following is the definition of the second class
[code3]template <class keyType>
class BTree
//this is the full version of the BTree
{
protected:
typedof BTreeNode<keyType> BTNode; //useful shorthand
BTNode * FindLeaf (const keyType key);
//load a branch into memory down to the leaf with key
BTNode * NewNode ();
BTNode * Fetch (const int recaddr);
int Store (BTNode *);
BTNode Root;
int Height; //hight of tree
int Order; //order of tree
int PoolSize;
BTNode ** Nodes; //pool of available nodes
//Nodes[1] is level 1, etc. (see FindLeaf)
//Nodes[Height-1] is leaf
FixedFieldBuffer Buffer;
RecordFile<BTNode> BTreeFile;
public:
BTree (int order, int keySize = sizeof(keyType), int unique = 1);
~BTree ();
int Open (char * name, int mode);
int Create (char * name, int mode);
int Close ();
int Insert (const keyType key, const int recAddr);
int Remove (const keyType key, const int recAddr = -1);
int Search (const keyType key, const int recAddr = -1);
void Print (ostream &);
void Print (ostream &, int nodeAddr, int level);
};
[/code3]
and the following is the implementation of second class
[code4]#include <iostream.h>
#include "Btree definition.h"
const int MaxHeight = 5;
template <class keyType>
BTree<keyType> :: BTree (int order, int keySize, int unique):
Buffer (1+2*order, sizeof(int)+order*keySize+order*sizeof(int)),
BTreeFile(Buffer), Root(order)
{
Height = 1;
Order = order;
PoolSize = MaxHeight*2;
Nodes = new BTndoe * [PoolSize];
BTNode :: InitBuffer(Buffer, order);
Nodes[0] = &Root;
}
//---------------------------------------------------------
template <class keyType>
BTree<keyType> :: ~BTree()
{
Close();
delete Nodes;
}
//---------------------------------------------------------
template <class keyType>
int BTree<keyType> :: Open (char * name, int mode)
{
int result;
result = BTreeFile.Open(name, mode);
if(!result)
return result;
//load root
BTreeFile.Read(Root);
Height = 1; //find height from BTreeFile
return 1;
}
//------------------------------------------------
template <class keyType>
intBTree<keyType> :: Create(char * name, int mode)
{
int result;
result = BTreeFile.Create(name, mode);
if(!result)
return result;
//append root node
result = BTreeFile.Write(Root);
Root.RecAddr = result;
return result != -1;
}
//------------------------------------------------------
template <class keyType>
int BTree<keyType> :: Close ()
{
int result;
result = BTreeFile.Rewind();
if(!result)
return result;
result = BTreeFile.Write(Root);
if(result == -1)
return 0;
return BTreeFile.Close();
}
//-------------------------------------------------------
template <class keyType>
int BTree<keyType> :: Insert (const keyType key, const int recAddr)
{
int result;
int level = Height-1;
int newLargest=0;
keyType prevkey, largestkey;
BTNode * thisNode, * newNode, * parentNode;
thisNode = FindLeaf (key);
//test for special case of new largest key in tree
if(key > thisNode->Largestkey())
{newLargest = 1; prevkey=thisNode->Largestkey();}
result = thisNode -> Insert(key, recAddr);
//handle special case of new largest key in tree
if(newLargest)
for(int i =0; i<Height-1; i++)
{
Nodes -> Updatekey(prevkey, key);
if(i>0)
Store (Nodes);
}
while (result == -1) //if overflow and not root
{
//remember the largest key
largestkey = thisNode->Largestkey();
//split the node
newNode = Newnode();
thisNode->Split(newNode);
level--; //go up to parent level
if(level < 0) break;
//insert newNode into parent of thisNode
parentNode = Nodes[level];
result = parentNode->Updatekey
(largestkey, thisNode->Largestkey());
result = parentNode->Insert
(newNode->Largestkey(), newNode->RecAddr);
thisNode = parentNode;
}
Store (thisNode);
if (level >= 0)
return 1; //insert complete
//else we just split the root
int newAddr = BTreeFile.Append(Root);
//put previous root into file
//insert 2 keys in new root node
Root.keys[0]=thisNode->Largestkey();
Root.RecAddrs[0]=newAddr;
Root.keys[1]=newNode->Largestkey();
Root.RecAddrs[1]=newNode->RecAddr;
Root.Numkeys=2;
Height++;
return 1;
}
//------------------------------------------------------------
template <class keyType>
int BTree<keyType> :: Remove (const keyType key, const int recAddr)
{
//left for exercise
return -1;
}
//-------------------------------------------------------------
template <class keyType>
int BTree<keyType> :: Search (const keyType key, const int recAddr)
{
BTNode * leafNode;
leafNode = Findleaf (key);
return leafNode -> Search(key, recAddr);
}
//-----------------------------------------------------------
template <class keyType>
void BTree<keyType> :: Print(ostream & stream)
{
stream << "BTree of height "<<Height<<" is "<<endl;
Root.Print(stream);
if(Height > 1)
for(int i =0; i <Root.numkeys(); i++)
{
Print(stream, Root.RecAddrs, 2);
}
stream << "end of BTree" <<endl;
}
//------------------------------------------------------
template <class keyType>
void BTree<keyType> :: Print(ostream & stream, int nodeAddr, int level)
{
BTNode * thisNode = Fetch(nodeAddr);
stream << "Node at level " << level << "address "<<nodeAddr <<' ';
thisNode -> Print(stream);
if(Height > level)
{
level++;
for(int i =0; i<thisNode->numkeys(); i++)
{
Print(stream, thisNode->RecAddrs, level);
}
stream << "end of level " <<level<<endl;
}
}
//-----------------------------------------------------------
template <class keyType>
BTreeNode<keyType> * BTree<keyType> :: FindLeaf (const keyType key)
//load a branch into memory down to the leaf with key
{
int recAddr, level;
for(level =1; level < Height; level++)
{
recAddr = Nodes[level-1]->Search(key,-1,0); //inexact search
Nodes[level] = Fetch(recAddr);
}
return Nodes[level-1];
}
//---------------------------------------------------------------
template <class keyType>
BTreeNode<keyType> * BTree<keyType> :: NewNode ()
{
//create a fresh node , insert into tree and set RecAddr member
BTNode * newnode = new BTNode(Order);
int recAddr = BTreeFile.Append(* newNode);
newNode -> RecAddr = recAddr;
return newNode;
}
//---------------------------------------------------------
template <class keyType>
int BTree<keyType> :: Store (BTree<keyType> * thisNode)
{
return BTreeFile.Write(*thisNode, thisNode -> RecAddr);
}
//----------------------------------------------------------
[/code4]
and the following is the main program
[code5]#include <conio.h>
#include <fstream.h>
#include "Btnode implement.tc.h"
#include "Btree implement.tc.h"
const char * keys="CSDTAMPIBWNGURKEHOLJYQZFXV";
const int BTreeSize = 4;
main(int argc, char * argv)
{
int result,i;
BTree <char> bt (BTreeSize);
result = bt.Create ("testbt.dat", ios::in || ios::out);
if(!result)
{
cout << "Please delete testbt.dat" <<endl;
return 0;
}
for(i =0; i<26; i++)
{
cout<<"Inserting " <<keys <<endl;
result = bt.Insert(keys,i);
bt.Print(cout);
}
bt.Search(1,1);
return 1;
getch();
}[/code5]
آسف على الإطالة وتقبلوا منى تحياتى
وأرجو من حضراتكم الرد بسرعة عشان مسافر وشكرا جزيلا
آسف معلهش الأكواد اتلخبطط منى لأنى أول مرة أستخدم الأكواد والإقتباسات والوسوم فى مشاركاتى
شكرا على تقديركم وبارك الله فيكم وجزاكم الله خيرا
وياريت بردو لو حد يرشدنى لموضوع الكتابة بلا أخطاء فى هذا المجال وشكر الله لكم