// Find the ArrayRow for this row. // If create is true, create the ArrayRow if it doesn't exist. private IntArrayRow FindRow(int row, bool create) { // Find the ArrayRow before the one we want. IntArrayRow before = FindRowBefore(row); // If we found it, return it. if ((before.NextRow != null) && (before.NextRow.RowNumber == row)) { return(before.NextRow); } // We didn't find it. See if we should create it. if (create) { // Create the new ArrayRow. IntArrayRow newRow = new IntArrayRow(); newRow.RowNumber = row; // Insert it in the row list. newRow.NextRow = before.NextRow; before.NextRow = newRow; // Create the row's sentinel. newRow.RowSentinel = new IntArrayEntry(); newRow.RowSentinel.NextEntry = null; // Return it. return(newRow); } // We didn't find it and shouldn't create it. Return null. return(null); }
// Create the sentinels. public SparseIntArray(int defaultValue) { // Save the default value. DefaultValue = defaultValue; // Create the row sentinel. TopSentinel = new IntArrayRow(); TopSentinel.NextRow = null; }
// Find the ArrayRow before this row. private IntArrayRow FindRowBefore(int row) { // Start at the sentinel. IntArrayRow arrayRow = TopSentinel; // Find the row before the required one. while ((arrayRow.NextRow != null) && (arrayRow.NextRow.RowNumber < row)) { arrayRow = arrayRow.NextRow; } // Return the ArrayRow before the row or null. return(arrayRow); }
// Find the ArrayEntry for this row and column. // If create is true, create the ArrayEntry if it doesn't exist. private IntArrayEntry FindEntry(int row, int col, bool create) { // Find the entry's row. IntArrayRow arrayRow = FindRow(row, create); // If we didn't find it (or create it), return null. if (arrayRow == null) { return(null); } // Find the entry in this row and return it. return(FindColumn(arrayRow.RowSentinel, col, create)); }
// Delete the indicated entry if it exists. public void DeleteEntry(int row, int col) { // Find the row before the entry's row. IntArrayRow rowBefore = FindRowBefore(row); // If we didn't find the row, we're done. IntArrayRow arrayRow = rowBefore.NextRow; if ((arrayRow == null) || (arrayRow.RowNumber != row)) { return; } // Find the entry before this entry's entry. IntArrayEntry entryBefore = FindColumnBefore(arrayRow.RowSentinel, col); IntArrayEntry arrayEntry = entryBefore.NextEntry; // If we didn't find the entry, we're done. if ((arrayEntry == null) || (arrayEntry.ColumnNumber != col)) { return; } // Remove the entry from the row's list. entryBefore.NextEntry = arrayEntry.NextEntry; // arrayEntry.NextEntry = null; // free(arrayEntry); // If there are no more entries in the row, remove it. IntArrayEntry arraySentinel = arrayRow.RowSentinel; if (arraySentinel.NextEntry == null) { rowBefore.NextRow = arrayRow.NextRow; // arrayRow.RowSentinel = null; // free(arraySentinel); // free(arrayRow); } }
// Add two SparseArrays representing matrices. public SparseIntArray Add(SparseIntArray other) { SparseIntArray result = new SparseIntArray(this.DefaultValue); // Variables to move through all of the arrays. IntArrayRow array1Row = this.TopSentinel.NextRow; IntArrayRow array2Row = other.TopSentinel.NextRow; IntArrayRow resultRow = result.TopSentinel; while ((array1Row != null) && (array2Row != null)) { // Make a new result row. resultRow.NextRow = new IntArrayRow(); resultRow = resultRow.NextRow; resultRow.RowSentinel = new IntArrayEntry(); resultRow.NextRow = null; // See which input row has the smaller row number. if (array1Row.RowNumber < array2Row.RowNumber) { // array1Row comes first. Copy its values into result. resultRow.RowNumber = array1Row.RowNumber; CopyEntries(array1Row.RowSentinel.NextEntry, resultRow.RowSentinel); array1Row = array1Row.NextRow; } else if (array2Row.RowNumber < array1Row.RowNumber) { // array2Row comes first. Copy its values into result. resultRow.RowNumber = array2Row.RowNumber; CopyEntries(array2Row.RowSentinel.NextEntry, resultRow.RowSentinel); array2Row = array2Row.NextRow; } else { // The row numbers are the same. Add their values. resultRow.RowNumber = array1Row.RowNumber; AddEntries( array1Row.RowSentinel.NextEntry, array2Row.RowSentinel.NextEntry, resultRow.RowSentinel); array1Row = array1Row.NextRow; array2Row = array2Row.NextRow; } } // Add any remaining rows. if (array1Row != null) { // Make a new result row. resultRow.NextRow = new IntArrayRow(); resultRow = resultRow.NextRow; resultRow.RowNumber = array1Row.RowNumber; resultRow.RowSentinel = new IntArrayEntry(); resultRow.NextRow = null; CopyEntries(array1Row.RowSentinel.NextEntry, resultRow.RowSentinel); } if (array2Row != null) { // Make a new result row. resultRow.NextRow = new IntArrayRow(); resultRow = resultRow.NextRow; resultRow.RowNumber = array2Row.RowNumber; resultRow.RowSentinel = new IntArrayEntry(); resultRow.NextRow = null; CopyEntries(array2Row.RowSentinel.NextEntry, resultRow.RowSentinel); } return(result); }