/* * freeItemDataStruct * ---------------------------------- * * Unallocates a void* data interpreting it as an ItemData*. * * @item --------------------> Void* to interpret as ItemData* and unallocate. * * @return ------------------> None. * */ void freeItemDataStruct( void* item ){ ItemData* i = (ItemData*)item; if( i == NULL ){ return; } unallocate( i->author ); unallocate( i->title ); // numCopies gets taken care of when full struct is unallocated ListNode* nodeToDelete = i->patronsCurrentlyRenting; while( nodeToDelete != NULL ){ ListNode* next = nodeToDelete->next; // Get data, its a pointer to a ListNode containing an patron PatronData* patronToCollectFrom = (PatronData*)((ListNode*) nodeToDelete->data)->data; // find listnode with data address of p deleteNode( &patronToCollectFrom->itemsCurrentlyRenting, findNodeWithData( patronToCollectFrom->itemsCurrentlyRenting, i ), NULL ); unallocate( nodeToDelete ); nodeToDelete = next; } unallocate( i ); }
/*! * Найти вершину, цифра, присвоенная которой присутствует в обоих деревьях, и размер общего поддерева в которой максимальный * \param[in] root1 - указатель на корень первого дерева * \param[in] root2 - указатель на корень второго дерева * \param[out] retRoot - указатель на корень найденного максимального общего поддерева * \return - максимальный размер общего поддерева двух деревьев */ int findRootMaxCommonTree(node* root1, node* root2, node*& retRoot){ if (root1 == NULL || root2 == NULL){ retRoot = NULL; return 0; } retRoot = NULL; int retSize = 0; // 1. Найти вершину sameData в дереве root2, которая содержит цифру, одинаковую с цифрой в вершине root1, с помощью функции findNodeWithData node* sameData = findNodeWithData(root2, root1->data); // 2. Если соответственная вершина найдена, то if (sameData != NULL){ node* temp; // 2.1. Вызвать функцию computeCommonTree, чтобы найти максимальное общее поддерево с корнем в вершине, которая содержит цифру в вершинах root1 и sameData int c = computeCommonTree(root1, sameData, temp); // 2.2. Сохранить корень с максимальным размером if (c > retSize){ retSize = c; retRoot = temp; } } int n = root1->children.size(); // 3. Для каждой дочери вершины root1 с цифрой, которую не содержат дочери вершины sameData for (int i = 0; i < n; i++){ node* temp = NULL; // флаг - дочери вершины sameData содержат ли цифрой, которую содержит i-ая дочь bool check = false; int m = sameData->children.size(); // Для каждой дочери вершины sameData for (int j = 0; j < m; j++) if (sameData->children[j]->data == root1->children[i]->data){ // флаг - истинный check = true; break; } if (!check){ // 3.1. Вызвать рекурсивно эту же функцию, чтобы найти максимальное общее поддерево с корнем в этих подвершинах. int c = findRootMaxCommonTree(root1->children[i], root2, temp); // 3.2. Сравнить с текущим максимальным размером. Если новый считающий размер больше, то сохранить корень общего поддерева с максимальным размером. if (c > retSize){ retSize = c; retRoot = temp; } } } return retSize; }
/*! * Найти вершину в поддереве с корнем в вершине currentNode, которая содержит цифру data * \param[in] currentNode - указатель на коренную вершину поддерева * \param[in] data - цифра, которую надо найти * \return - указатель на вершину, которая держит цифру data. Если не существует эта вершина, то вернуть NULL */ node* findNodeWithData(node* currentNode, int data){ if (currentNode == NULL) return NULL; // 1. Если цифра в вершине currentNode равна data, то вернуть эту вершину if (currentNode->data == data) return currentNode; node* ret = NULL; // 2. Вызвать рекурсивно себя для всех дочерей вершины currentNode, до тех по пока не нашли результирующую вершину int n = currentNode->children.size(); for (int i = 0; i < n; i++){ ret = findNodeWithData(currentNode->children[i], data); if (ret != NULL) return ret; } // 3. Если вершина не найдена, то вернуть NULL return ret; }
/* * freePatronDataStruct * ---------------------------------- * * Unallocates a void* data interpreting it as an PatronData*. * * @patron ------------------> Void* to interpret as PatronData* and unallocate. * * @return ------------------> None. * */ void freePatronDataStruct( void* patron ){ PatronData* p = (PatronData*)patron; if( p == NULL ){ return; } unallocate( p->name ); // pid gets taken care of when full struct is unallocated // unallocate the actual nodes of items currently renting // dont worry about the void* data in them because those point to // other item nodes that will take care of themselves ListNode* nodeToDelete = p->itemsCurrentlyRenting; while( nodeToDelete != NULL ){ ListNode* next = nodeToDelete->next; // this is a node // it has a void* data which contains an address of a listnode // whom contains a void* data to an item // go to this other listnode and cast its void* data to an item // within this item loop through its patronsCurrentlyrenting LL // find the node containg a void* data with the patrons address // delete this node // Get data, its a pointer to a ListNode containing an item ItemData* itemToReturn = (ItemData*)((ListNode*)nodeToDelete->data)->data; // find listnode with data address of p ListNode* pcr = itemToReturn->patronsCurrentlyRenting; deleteNode( &pcr, findNodeWithData( pcr, p ), NULL ); unallocate( nodeToDelete ); nodeToDelete = next; } unallocate( p ); }