// get node whith used box that exist in queue and move to the end of queue (if this node is empty - delete) public void MoveToEnd(CombinedNode usedNode) { // avoid using nodes which data is null if (usedNode.Data == null) { throw new EmptyBoxSectionException("Error: tried move or delete node without data in the queue"); } // check if it exist if ((usedNode.Pre != null || usedNode.Next != null) || (usedNode == _tail && usedNode == _head)) { // if used-box became empty-section - delete it if (usedNode.Data.IsEmpty) { Delete(usedNode); } // if it's not empty and not already in the end else if (usedNode != _tail) { Delete(usedNode); Enqueue(usedNode); } } }
// Public remove by CombynedNode (for queue-use & call by main-tree) - implementation for abstract-method public override void Delete(CombinedNode removingNode) { if (removingNode.Data == null) { throw new EmptyBoxSectionException("Error: tried delete node without data from sub-tree"); } DelAndReconnect(removingNode); }
// enter new node with box in the gueue private void InsertTail(CombinedNode newNode) { if (IsEmpty) { _head = newNode; _tail = newNode; } else { _tail.Next = newNode; newNode.Pre = _tail; _tail = newNode; } }
// delete methods // when exist only 1 node in the queue private CombinedNode DeleteSingleNode() { if (_head == _tail) { CombinedNode temp = _head; _tail = null; _head = null; return(CleanLinks(temp)); } else { return(null); } }
// Public remove by CombynedNode (for queue-use) - implementation for abstract-method public override void Delete(CombinedNode removingNode) { // avoid using nodes which data is null if (removingNode.Data == null) { throw new EmptyBoxSectionException("Error: tried delete node without data in the main-tree"); } Node <SubTree> current = removingNode.MainNode; current.Data.Delete(removingNode); if (current.Data.IsEmpty) { DelAndReconnect(current); } }
// enter new node with box in the gueue (insert tail), check if it exist here already public void Enqueue(CombinedNode newNode) { if (newNode != null) { // avoid using nodes which data is null if (newNode.Data == null) { throw new EmptyBoxSectionException("Error: tried enter node without data in the queue"); } // check it it exist by checking his pre and next nodes (+ check if it the same instase of tail and head - it may heppend when the que have only 1 node - so this node have no pre and next) if (newNode.Pre == null && newNode.Next == null && newNode != _head && newNode != _tail) { InsertTail(newNode); } } }
// delete last node private void DeleteTail() { if (!IsEmpty) { if (_head != _tail) { CombinedNode temp = _tail; _tail.Pre.Next = null; _tail = _tail.Pre; CleanLinks(temp); } else { DeleteSingleNode(); } } }
// get list of all boxes in the queue (for printing) public List <Box> InOrder() { if (!IsEmpty) { List <Box> temp = new List <Box>(); CombinedNode current = _head; while (current != null) { temp.Add(current.Data); current = current.Next; } return(temp); } else { return(null); } }
// delete node from unknown place private void Delete(CombinedNode delNode) { if (!IsEmpty) { if (delNode == _head) { DeleteHead(); } else if (delNode == _tail) { DeleteTail(); } else { delNode.Pre.Next = delNode.Next; delNode.Next.Pre = delNode.Pre; CleanLinks(delNode); } } }
// delete first node private CombinedNode DeleteHead() { if (!IsEmpty) { if (_head != _tail) { CombinedNode temp = _head; _head.Next.Pre = null; _head = _head.Next; return(CleanLinks(temp)); } else { return(DeleteSingleNode()); } } else { return(null); } }
// zeroing pre and next of returning deleted node (if the same instanse wil pushed in the queue again private CombinedNode CleanLinks(CombinedNode deleted) { deleted.Pre = null; deleted.Next = null; return(deleted); }
// Methods For Remove Node // Public apstract remove by CombynedNode (for queue-use & internal call Del-method) public abstract void Delete(CombinedNode removingNode);
// implementation for abstract method to insert new box to storage protected override Node <Box> Insert(Box newBox, ref Node <Box> currentNode) { if (currentNode == null) { Respone <Box> feedback = new Respone <Box>(); if (newBox.Quantity > FromConfig.MaxBoxesSameSize) { feedback.IsWorking = false; if (FromConfig.MaxBoxesSameSize > 0) { newBox.Quantity = FromConfig.MaxBoxesSameSize; feedback.Message = $"Tried insert more boxes than maximum capacity. Inserted only {newBox.Quantity} boxes"; } else { throw new ConfigInvalidDataException("Configuration error: maximum capasity is 0 or less!"); } } else { feedback.IsWorking = true; } currentNode = new CombinedNode(_creator) { Data = newBox }; LastUsedBox = (CombinedNode)currentNode; feedback.Data = currentNode.Data; InsertFeedback = feedback; } else if (Compare(currentNode.Data, newBox) < 0) { Insert(newBox, ref currentNode.Right).Root = currentNode; } else if (Compare(currentNode.Data, newBox) > 0) { Insert(newBox, ref currentNode.Left).Root = currentNode; } else { Respone <Box> feedback = new Respone <Box>(); if ((currentNode.Data.Quantity + newBox.Quantity) > FromConfig.MaxBoxesSameSize) { if (FromConfig.MaxBoxesSameSize <= 0) { throw new ConfigInvalidDataException("Configuration error: maximum capasity is 0 or less!"); } if (FromConfig.MaxBoxesSameSize < currentNode.Data.Quantity) { throw new ConfigInvalidDataException("Configuration error: quantity of existing boxes is more then maximum capacity"); } feedback.IsWorking = false; if (FromConfig.MaxBoxesSameSize == currentNode.Data.Quantity) { feedback.Message = "Can't insert boxes of this size: it's already maximum quantity"; } else { feedback.Message = $"Tried insert more boxes than maximum capacity. Inserted only {FromConfig.MaxBoxesSameSize - currentNode.Data.Quantity} box(es)"; currentNode.Data.Quantity = FromConfig.MaxBoxesSameSize; } } else { currentNode.Data.Quantity += newBox.Quantity; feedback.IsWorking = true; } feedback.Data = currentNode.Data; InsertFeedback = feedback; LastUsedBox = null; } return(currentNode); }