// Return true if the list contains a loop. public bool ContainsLoop() { // Lists with 0 or 1 items don't contain loops. if ((this.Next == null) || (this.Next.Next == null)) { return(false); } ValueCell slowCell = this.Next; ValueCell fastCell = slowCell.Next; // Start the cells running. for (; ;) { if (slowCell == fastCell) { return(true); } slowCell = slowCell.Next; fastCell = fastCell.Next; if (fastCell.Next == null) { return(false); } fastCell = fastCell.Next; if (fastCell.Next == null) { return(false); } } }
// Make a list that contains a loop. private void BuildList() { // Make some cells. ValueCell[] cells = new ValueCell[NumCells]; for (int i = 0; i < cells.Length; i++) { cells[i] = new ValueCell(); cells[i].Value = i + 1; } // Link the cells. for (int i = 0; i < cells.Length - 1; i++) { cells[i].Next = cells[i + 1]; } // Make the loop. cells[cells.Length - 1].Next = cells[LoopCell]; // Prepare the sentinel. TopCell = new ValueCell() { Next = cells[0] }; }
// Display the list in the indicated ListBox. private void DisplayList(ListBox lst) { // The maximum number of cells we will list. const int maxCells = 14; // Display list. lst.Items.Clear(); int cellNum = 0; for (ValueCell cell = TopCell.Next; cell != null; cell = cell.Next) { lst.Items.Add(cell.Value); // Stop after a while. if (++cellNum > maxCells) { lst.Items.Add("..."); break; } } }
// If this list after this cell contains a loop, // break it so we have a normal list. public void BreakLoop() { if (!ContainsLoop()) { return; } ValueCell slowCell = this.Next; ValueCell fastCell = slowCell.Next; // Start the cells running and see where they meet. for (; ;) { if (slowCell == fastCell) { break; } slowCell = slowCell.Next; fastCell = fastCell.Next; fastCell = fastCell.Next; } // Start slowCell again at the beginning and // run the two at the same speed until their Next // cells are the same. slowCell = this; while (slowCell.Next != fastCell.Next) { slowCell = slowCell.Next; fastCell = fastCell.Next; } // At this point, slowCell.Next is the first cell in the // loop and lastCell.Next is the last cell in the loop. fastCell.Next = null; }