为有兴趣的人解决了以下问题:
var table = [
{i: 0, id: 0, id2: 0, id3: 0},
{i: 1, id: 0, id2: 1, id3: 0},
{i: 2, id: 1, id2: 0, id3: 0},
{i: 3, id: 1, id2: 2, id3: 0},
{i: 4, id: 1, id2: 3, id3: 0},
{i: 5, id: 2, id2: 0, id3: 1},
{i: 6, id: 2, id2: 0, id3: 2},
{i: 7, id: 2, id2: 1, id3: 0},
{i: 8, id: 2, id2: 1, id3: 1},
{i: 9, id: 2, id2: 2, id3: 0}
];
var sort = ['id', 'id2'];
function InsertionIndex(table, sort, row) {
var state = {
_compare: function (left, right) {
if (left < right) { return (1); }
else if (left > right) { return (-1); }
return (0);
},
column: '',
max: table.length,
min: 0,
row: row,
_search: function (state) {
var minc = this._compare(this.table[this.min][this.column], state.row[this.column]);
var maxc = this._compare(this.table[this.max - 1][this.column], this.row[this.column]);
if (state.table[state.min][state.column] == state.table[state.max - 1][state.column]) { return; }
if (minc < 0) { state.max = state.min; return; }
if (maxc > 0) { state.min = state.max; return; }
if ((state.max - state.min) > 2) {
var mid = Math.ceil((state.min + state.max) / 2);
var midc = state._compare(state.table[mid][state.column], state.row[state.column]);
if (midc < 0) {
state.max = mid;
state._search(state);
return;
} else if (midc > 0) {
state.min = mid;
state._search(state);
return;
} else {
for (var i = mid - 1; i >= state.min; i--) { if (state._compare(state.table[i][state.column], state.row[state.column]) != 0) { state.min = i + 1; break; } }
for (var i = mid + 1; i < state.max; i++) { if (state._compare(state.table[i][state.column], state.row[state.column]) != 0) { state.max = i; break; } }
return;
}
} else {
if (maxc < 0) {
if (minc > 0) { state.min = state.max - 1; state.max = state.max - 1; return; }
else { state.max = state.max - 1; return; }
} else if (minc > 0) {
state.min = state.max - 1; return;
}
}
return;
},
table: table
};
for (var i = 0; i < sort.length; i++) {
state.column = sort[i];
state._search(state);
if (state.min >= state.max) { break; }
}
return ({ max: state.max, min: state.min });
}
for (var i = 0; i < table.length; i++) {
document.write(table[i].i + ' ' + table[i].id+ ' ' + table[i].id2 + ' ' + table[i].id3 + '<BR />');
}
var insertion = {i: 3, id: 0, id2: 1, id3: 1};
document.write(InsertionIndex(table, sort, insertion).min + ' ' + InsertionIndex(table, sort, insertion).max + ' 1 2<BR />');
insertion = {i: 3, id: 1, id2: 1, id3: 1};
document.write(InsertionIndex(table, sort, insertion).min + ' ' + InsertionIndex(table, sort, insertion).max + ' 3 3<BR />');
insertion = {i: 3, id: 2, id2: 1, id3: 1};
document.write(InsertionIndex(table, sort, insertion).min + ' ' + InsertionIndex(table, sort, insertion).max + ' 7 9<BR />');
insertion = {i: 3, id: 3, id2: 1, id3: 1};
document.write(InsertionIndex(table, sort, insertion).min + ' ' + InsertionIndex(table, sort, insertion).max + ' 10 10<BR />');