📄 sofl_05.cc
字号:
// file: $isip/class/io/SofList/sofl_05.cc// version: $Id: sofl_05.cc,v 1.5 2001/04/24 16:33:18 duncan Exp $//// isip include files//#include "SofList.h"#include <MemoryManager.h>#include <Console.h>// method: add//// arguments:// long name: (input) object name// long tag: (input) object tag// long pos: (input) object position// long size: (input) object size//// return: a boolean value indicating status//// add a new node to the list//boolean SofList::add(long name_a, long tag_a, long pos_a, long size_a) { // check argument // if (name_a == SofSymbolTable::NO_SYMB) { return Error::handle(name(), L"add", Error::ARG, __FILE__, __LINE__); } // we need a new node to hold this, declare and copy data // SofNode* tmp = newNode(); tmp->name_d = name_a; tmp->tag_d = tag_a; tmp->pos_d = pos_a; tmp->size_d = size_a; // add the new node // return addNode(tmp);}// method: addQuick//// arguments:// long name: (input) object name// long tag: (input) object tag// long pos: (input) object position// long size: (input) object size//// return: a boolean value indicating status//// add a new node to the list quickly. this method assumes that the// previous call added a node that is less than the current node and// will fall directly adjacent to the new node, hence no tree// searching is necessary. this speeds up the common case of adding// consecutive tokens for the same object in SofParser.//boolean SofList::addQuick(long name_a, long tag_a, long pos_a, long size_a) { // we need a new node to hold this, declare and copy data // SofNode* tmp = newNode(); tmp->name_d = name_a; tmp->tag_d = tag_a; tmp->pos_d = pos_a; tmp->size_d = size_a; // make sure the right branch is null // if ((current_d == (SofNode*)NULL) || (current_d->right_d != (SofNode*)NULL)) { return Error::handle(name(), L"addQuick", ERR, __FILE__, __LINE__); } // add this directly to the right of the current node // current_d->right_d = tmp; tmp->parent_d = current_d; current_d = tmp; // exit gracefully // return true;}// method: addNode//// arguments:// SofNode* node: (input) node to add into tree//// return: a boolean value indicating status//// add the new node to the tree//boolean SofList::addNode(SofNode* node_a) { // check for special case of this being the first node // if (root_d == (SofNode*)NULL) { root_d = node_a; node_a->parent_d = (SofNode*)NULL; current_d = root_d; return true; } // now find a space in the tree // SofNode* node = root_d; // when we find the space, we reset the tmp pointer // while (node_a != (SofNode*)NULL) { // compare the new node against the current // // if lesser, move to the left // if (nodeLt(node_a, node)) { if (node->left_d != (SofNode*)NULL) { node = node->left_d; } else { node->left_d = node_a; node_a->parent_d = node; current_d = node_a; node_a = (SofNode*)NULL; } } // if greater, move to the right // else if (nodeGt(node_a, node)) { if (node->right_d != (SofNode*)NULL) { node = node->right_d; } else { node->right_d = node_a; node_a->parent_d = node; current_d = node_a; node_a = (SofNode*)NULL; } } // if equal, we error. note that placing the check here is more // efficient then calling the find() method outside of this // method. // else { SysString output(L"Object "); if (table_d != (SofSymbolTable*)NULL) { SysString n; table_d->getSymbol(n, node_a->name_d); output.concat(L"'"); output.concat(n); output.concat(L"'"); } else { output.concat(L"[#"); output.concat(node_a->name_d); output.concat(L"]"); } output.concat(L" has been defined multiple times.\n"); Console::put(output); return Error::handle(name(), L"addNode", ERR_EXISTS, __FILE__, __LINE__, Error::WARNING); } } // exit gracefully // return true;}// method: remove//// arguments: none//// return: a boolean value indicating status//// delete the current node from the tree//boolean SofList::remove() { // check the current node // if (current_d == (SofNode*)NULL) { return Error::handle(name(), L"remove", ERR_CURR, __FILE__, __LINE__); } SofNode** parent_ptr = (SofNode**)NULL; // if the parent is null, this is the root node // if (current_d->parent_d == (SofNode*)NULL) { parent_ptr = &root_d; } // determine if this is the left or right node // else if (current_d->parent_d->left_d == current_d) { parent_ptr = &(current_d->parent_d->left_d); } else if (current_d->parent_d->right_d == current_d) { parent_ptr = &(current_d->parent_d->right_d); } // if either of the children are null, just pop the other child up // to take the place of the node which is leaving // if (current_d->left_d == (SofNode*)NULL) { *parent_ptr = current_d->right_d; if (current_d->right_d != (SofNode*)NULL) { current_d->right_d->parent_d = current_d->parent_d; } deleteNode(current_d); } else if (current_d->right_d == (SofNode*)NULL) { *parent_ptr = current_d->left_d; if (current_d->left_d != (SofNode*)NULL) { current_d->left_d->parent_d = current_d->parent_d; } deleteNode(current_d); } // both children exist. set the parent to point to the left and // re-insert the right. // else { SofNode* tmp = current_d->right_d; *parent_ptr = current_d->left_d; current_d->left_d->parent_d = current_d->parent_d; deleteNode(current_d); // tmp, the right leaf, is now unlinked, so re-insert it // tmp->parent_d = (SofNode*)NULL; addNode(tmp); } // exit gracefully // return true;}//-----------------------------------------------------------------------------//// the below methods have to be in the same file so they can utilize the// same static MemoryManager////-----------------------------------------------------------------------------static MemoryManager mgr(sizeof(SofNode));// method: newNode//// arguments: none//// return: a pointer to a new node//// get and initialize a new node//SofNode* SofList::newNode() { // grab a node from the memory manager // SofNode* tmp = (SofNode*)mgr.get(); // leave the node data (name, tag, pos, size) undefined // // clear the pointers // tmp->left_d = (SofNode*)NULL; tmp->right_d = (SofNode*)NULL; tmp->parent_d = (SofNode*)NULL; // return the new node // return tmp;}// method: deleteNode//// arguments:// SofNode* node: (input) node to be deleted//// return: a boolean value indicating status//// note: this node better be unlinked or we will have problems//boolean SofList::deleteNode(SofNode* node_a) { // give the node back to the manager // mgr.release(node_a); // exit gracefully // return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -