1. 使用本章讨论的所有算法对字符串数据而非数字数据进行排序,并比较不同算法的执行 时间。这两者的结果是否一致呢?
function CArray(numElements) {
this.dataStore = [];
this.pos = 0;
this.numElements = numElements;
this.insert = insert;
this.toString = toString;
this.clear = clear;
this.setData = setData;
this.swap = swap;
/*
for ( var i = 0; i < numElements; ++i ) {
this.dataStore[i] = i;
}
*/
for ( var i = 0; i < numElements; ++i ) {
this.dataStore[i] = String.fromCharCode(65 + i % 26);
}
this.bubbleSort = bubbleSort;
this.selectionSort = selectionSort;
this.insertionSort = insertionSort;
this.gaps = [5,3,1];
this.shellsort = shellsort;
this.shellsort1 = shellsort1;
this.mergeSort = mergeSort;
this.mergeArrays = mergeArrays;
}
/*
function setData() {
for ( var i = 0; i < this.numElements; ++i ) {
this.dataStore[i] = Math.floor(Math.random() * (this.numElements + 1));
}
}
*/
function setData() {
for ( var i = 0; i < this.numElements; ++i ) {
this.dataStore[i] = String.fromCharCode(65 + Math.floor(Math.random() * 26));
}
}
function clear() {
for ( var i = 0; i < this.dataStore.length; ++i ) {
this.dataStore[i] = 0;
}
}
function insert(element) {
this.dataStore[this.pos++] = element;
}
function toString() {
var retstr = '';
for ( var i = 0; i < this.dataStore.length; ++i ) {
retstr += this.dataStore[i] + " ";
if (i > 0 & i % 10 == 0) {
retstr += "\n";
}
}
return retstr;
}
function swap(arr, index1, index2) {
var temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
function bubbleSort() {
for ( var i = this.dataStore.length; i > 1; --i) {
for ( var j = 0; j < i - 1; ++j ) {
if (this.dataStore[j] > this.dataStore[j + 1]) {
swap(this.dataStore, j, j + 1);
}
}
//console.log(this.dataStore);
}
}
function selectionSort() {
for (var i = 0; i < this.dataStore.length-1; ++i) {
for (var j = i + 1; j < this.dataStore.length; ++j) {
if (this.dataStore[j] < this.dataStore[i]) {
swap(this.dataStore, i, j);
}
}
//console.log(this.dataStore);
}
}
function insertionSort() {
for (var i = 1; i < this.dataStore.length; ++i) {
for (var j = i; j > 0; j--) {
if (this.dataStore[j - 1] > this.dataStore[j]) {
swap(this.dataStore, j, j - 1);
}
}
//console.log(this.dataStore);
}
}
function shellsort() {
for (var g = 0; g < this.gaps.length; ++g) {
for (var i = this.gaps[g]; i < this.dataStore.length; ++i) {
for (var j = i; j >= this.gaps[g] && this.dataStore[j-this.gaps[g]] > this.dataStore[j]; j -= this.gaps[g]) {
swap(this.dataStore, j, j - this.gaps[g]);
}
//console.log(this.dataStore);
}
}
}
function shellsort1() {
var N = this.dataStore.length;
var h = 1;
while (h < N/3) {
h = 3 * h + 1;
}
while (h >= 1) {
for (var i = h; i < N; i++) {
for (var j = i; j >= h && this.dataStore[j] < this.dataStore[j-h]; j -= h) {
swap(this.dataStore, j, j-h);
}
//console.log(this.dataStore);
}
h = (h-1)/3;
}
}
function mergeArrays(arr,startLeft, stopLeft, startRight, stopRight) {
var rightArr = arr.slice(startRight, stopRight + 1);
var leftArr = arr.slice(startLeft, stopLeft + 1);
rightArr.push(Infinity);
leftArr.push(Infinity);
var m = 0;
var n = 0;
for (var k = startLeft; k <= stopRight; ++k) {
if (leftArr[m] <= rightArr[n]) {
arr[k] = leftArr[m];
m++;
} else {
arr[k] = rightArr[n];
n++;
}
}
//console.log("left array - ", leftArr);
//console.log("right array - ", rightArr);
}
function mergeSort() {
if (this.dataStore.length < 2) {
return;
}
var step = 1;
while (step < this.dataStore.length) {
var left = 0;
var right = step;
while (right + step <= this.dataStore.length) {
mergeArrays(this.dataStore, left, left + step - 1, right, right + step - 1);
left = right + step;
right = left + step;
}
if (right < this.dataStore.length) {
mergeArrays(this.dataStore, left, left + step - 1, right, this.dataStore.length - 1);
}
step *= 2;
}
}
function qSort(list) {
if (list.length <= 1) {
return list;
}
var lesser = [];
var greater = [];
var equal = [];
var pivotIndex = Math.floor(list.length / 2);
var pivot = list[pivotIndex];
for (var i = 0; i < list.length; i++) {
if (i == pivotIndex) {
continue;
}
if (list[i] < pivot) {
lesser.push(list[i]);
} else if (list[i] > pivot) {
greater.push(list[i]);
} else {
equal.push(list[i]);
}
}
return qSort(lesser).concat([pivot], equal, qSort(greater));
}
function measureExecutionTime(sortFunction, context) {
var startTime = performance.now();
if (context instanceof CArray) {
sortFunction.call(context);
} else {
context = sortFunction(context);
}
var endTime = performance.now();
return endTime - startTime;
}
var numElements = 30000;
var cArray = new CArray(numElements);
cArray.setData();
var algorithms = [
{ name: 'Bubble Sort', func: cArray.bubbleSort, context: cArray },
{ name: 'Selection Sort', func: cArray.selectionSort, context: cArray },
{ name: 'Insertion Sort', func: cArray.insertionSort, context: cArray },
{ name: 'Shell Sort', func: cArray.shellsort, context: cArray },
{ name: 'Shell Sort 1', func: cArray.shellsort1, context: cArray },
{ name: 'Merge Sort', func: cArray.mergeSort, context: cArray },
{ name: 'Quick Sort', func: qSort, context: cArray.dataStore.slice() }
];
algorithms.forEach(algo => {
var time = measureExecutionTime(algo.func, algo.context);
console.log(`${algo.name}: ${time.toFixed(2)} ms`);
});//Bubble Sort: 3131.30 ms
//Selection Sort: 2211.20 ms
//Insertion Sort: 1556.70 ms
//Shell Sort: 2.30 ms
//Shell Sort 1: 2.30 ms
//Merge Sort: 18.80 ms
//Quick Sort: 5.60 ms
2. 创建一个包含 1000 个整数的有序数组。编写一个程序,用本章讨论的所有算法对这个 数组排序,分别记下它们的执行时间,并进行比较。如果对一个无序的数组进行排序结 果又会怎样?
function CArray(numElements) {
this.dataStore = [];
this.pos = 0;
this.numElements = numElements;
this.insert = insert;
this.toString = toString;
this.clear = clear;
this.setData = setData;
this.swap = swap;
for ( var i = 0; i < numElements; ++i ) {
this.dataStore[i] = i;
}
/*
for ( var i = 0; i < numElements; ++i ) {
this.dataStore[i] = String.fromCharCode(65 + i % 26);
}
*/
this.bubbleSort = bubbleSort;
this.selectionSort = selectionSort;
this.insertionSort = insertionSort;
this.gaps = [5,3,1];
this.shellsort = shellsort;
this.shellsort1 = shellsort1;
this.mergeSort = mergeSort;
this.mergeArrays = mergeArrays;
}
function setData() {
for ( var i = 0; i < this.numElements; ++i ) {
this.dataStore[i] = Math.floor(Math.random() * (this.numElements + 1));
}
}
/*
function setData() {
for ( var i = 0; i < this.numElements; ++i ) {
this.dataStore[i] = String.fromCharCode(65 + Math.floor(Math.random() * 26));
}
}
*/
function clear() {
for ( var i = 0; i < this.dataStore.length; ++i ) {
this.dataStore[i] = 0;
}
}
function insert(element) {
this.dataStore[this.pos++] = element;
}
function toString() {
var retstr = '';
for ( var i = 0; i < this.dataStore.length; ++i ) {
retstr += this.dataStore[i] + " ";
if (i > 0 & i % 10 == 0) {
retstr += "\n";
}
}
return retstr;
}
function swap(arr, index1, index2) {
var temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
function bubbleSort() {
for ( var i = this.dataStore.length; i > 1; --i) {
for ( var j = 0; j < i - 1; ++j ) {
if (this.dataStore[j] > this.dataStore[j + 1]) {
swap(this.dataStore, j, j + 1);
}
}
//console.log(this.dataStore);
}
}
function selectionSort() {
for (var i = 0; i < this.dataStore.length-1; ++i) {
for (var j = i + 1; j < this.dataStore.length; ++j) {
if (this.dataStore[j] < this.dataStore[i]) {
swap(this.dataStore, i, j);
}
}
//console.log(this.dataStore);
}
}
function insertionSort() {
for (var i = 1; i < this.dataStore.length; ++i) {
for (var j = i; j > 0; j--) {
if (this.dataStore[j - 1] > this.dataStore[j]) {
swap(this.dataStore, j, j - 1);
}
}
//console.log(this.dataStore);
}
}
function shellsort() {
for (var g = 0; g < this.gaps.length; ++g) {
for (var i = this.gaps[g]; i < this.dataStore.length; ++i) {
for (var j = i; j >= this.gaps[g] && this.dataStore[j-this.gaps[g]] > this.dataStore[j]; j -= this.gaps[g]) {
swap(this.dataStore, j, j - this.gaps[g]);
}
//console.log(this.dataStore);
}
}
}
function shellsort1() {
var N = this.dataStore.length;
var h = 1;
while (h < N/3) {
h = 3 * h + 1;
}
while (h >= 1) {
for (var i = h; i < N; i++) {
for (var j = i; j >= h && this.dataStore[j] < this.dataStore[j-h]; j -= h) {
swap(this.dataStore, j, j-h);
}
//console.log(this.dataStore);
}
h = (h-1)/3;
}
}
function mergeArrays(arr,startLeft, stopLeft, startRight, stopRight) {
var rightArr = arr.slice(startRight, stopRight + 1);
var leftArr = arr.slice(startLeft, stopLeft + 1);
rightArr.push(Infinity);
leftArr.push(Infinity);
var m = 0;
var n = 0;
for (var k = startLeft; k <= stopRight; ++k) {
if (leftArr[m] <= rightArr[n]) {
arr[k] = leftArr[m];
m++;
} else {
arr[k] = rightArr[n];
n++;
}
}
//console.log("left array - ", leftArr);
//console.log("right array - ", rightArr);
}
function mergeSort() {
if (this.dataStore.length < 2) {
return;
}
var step = 1;
while (step < this.dataStore.length) {
var left = 0;
var right = step;
while (right + step <= this.dataStore.length) {
mergeArrays(this.dataStore, left, left + step - 1, right, right + step - 1);
left = right + step;
right = left + step;
}
if (right < this.dataStore.length) {
mergeArrays(this.dataStore, left, left + step - 1, right, this.dataStore.length - 1);
}
step *= 2;
}
}
function qSort(list) {
if (list.length <= 1) {
return list;
}
var lesser = [];
var greater = [];
var equal = [];
var pivotIndex = Math.floor(list.length / 2);
var pivot = list[pivotIndex];
for (var i = 0; i < list.length; i++) {
if (i == pivotIndex) {
continue;
}
if (list[i] < pivot) {
lesser.push(list[i]);
} else if (list[i] > pivot) {
greater.push(list[i]);
} else {
equal.push(list[i]);
}
}
return qSort(lesser).concat([pivot], equal, qSort(greater));
}
var numElements = 30000;
var orderedArray = new CArray(numElements);
var unorderedArray = new CArray(numElements);
unorderedArray.setData();
function testSortingAlgorithms(array, name) {
console.log(`\n排序 ${name} 数组:`);
var arrays = [
{ name: '冒泡排序', method: 'bubbleSort' },
{ name: '选择排序', method: 'selectionSort' },
{ name: '插入排序', method: 'insertionSort' },
{ name: '希尔排序(固定间隔)', method: 'shellsort' },
{ name: '希尔排序(动态间隔)', method: 'shellsort1' },
{ name: '归并排序', method: 'mergeSort' },
{ name: '快速排序', method: 'qSort' }
];
arrays.forEach(({ name, method }) => {
var startTime = performance.now();
if (method === 'qSort') {
array.dataStore = qSort(array.dataStore.slice());
} else {
array[method]();
}
var endTime = performance.now();
console.log(`${name}: ${(endTime - startTime).toFixed(2)} 毫秒`);
});
}
testSortingAlgorithms(orderedArray, '有序');
testSortingAlgorithms(unorderedArray, '无序');
//排序 有序 数组:
//冒泡排序: 939.90 毫秒
//选择排序: 318.00 毫秒
//插入排序: 828.70 毫秒
//希尔排序(固定间隔): 2.50 毫秒
//希尔排序(动态间隔): 1.90 毫秒
//归并排序: 12.20 毫秒
//快速排序: 14.20 毫秒
//
//排序 无序 数组:
//冒泡排序: 1374.60 毫秒
//选择排序: 306.50 毫秒
//插入排序: 811.00 毫秒
//希尔排序(固定间隔): 1.20 毫秒
//希尔排序(动态间隔): 2.30 毫秒
//归并排序: 8.60 毫秒
//快速排序: 14.10 毫秒
3. 创建一个包含 1000 个整数的倒序数组。编写一个程序,用本章讨论的所有算法对这个 数组排序,分别记下它们的执行时间,并进行比较。
function CArray(numElements) {
this.dataStore = [];
this.pos = 0;
this.numElements = numElements;
this.insert = insert;
this.toString = toString;
this.clear = clear;
this.setData = setData;
this.swap = swap;
for ( var i = 0; i < numElements; ++i ) {
this.dataStore[i] = i;
}
/*
for ( var i = 0; i < numElements; ++i ) {
this.dataStore[i] = String.fromCharCode(65 + i % 26);
}
*/
this.bubbleSort = bubbleSort;
this.selectionSort = selectionSort;
this.insertionSort = insertionSort;
this.gaps = [5,3,1];
this.shellsort = shellsort;
this.shellsort1 = shellsort1;
this.mergeSort = mergeSort;
this.mergeArrays = mergeArrays;
}
function setData() {
for ( var i = 0; i < this.numElements; ++i ) {
this.dataStore[i] = Math.floor(Math.random() * (this.numElements + 1));
}
}
/*
function setData() {
for ( var i = 0; i < this.numElements; ++i ) {
this.dataStore[i] = String.fromCharCode(65 + Math.floor(Math.random() * 26));
}
}
*/
function clear() {
for ( var i = 0; i < this.dataStore.length; ++i ) {
this.dataStore[i] = 0;
}
}
function insert(element) {
this.dataStore[this.pos++] = element;
}
function toString() {
var retstr = '';
for ( var i = 0; i < this.dataStore.length; ++i ) {
retstr += this.dataStore[i] + " ";
if (i > 0 & i % 10 == 0) {
retstr += "\n";
}
}
return retstr;
}
function swap(arr, index1, index2) {
var temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
function bubbleSort() {
for ( var i = this.dataStore.length; i > 1; --i) {
for ( var j = 0; j < i - 1; ++j ) {
if (this.dataStore[j] > this.dataStore[j + 1]) {
swap(this.dataStore, j, j + 1);
}
}
//console.log(this.dataStore);
}
}
function selectionSort() {
for (var i = 0; i < this.dataStore.length-1; ++i) {
for (var j = i + 1; j < this.dataStore.length; ++j) {
if (this.dataStore[j] < this.dataStore[i]) {
swap(this.dataStore, i, j);
}
}
//console.log(this.dataStore);
}
}
function insertionSort() {
for (var i = 1; i < this.dataStore.length; ++i) {
for (var j = i; j > 0; j--) {
if (this.dataStore[j - 1] > this.dataStore[j]) {
swap(this.dataStore, j, j - 1);
}
}
//console.log(this.dataStore);
}
}
function shellsort() {
for (var g = 0; g < this.gaps.length; ++g) {
for (var i = this.gaps[g]; i < this.dataStore.length; ++i) {
for (var j = i; j >= this.gaps[g] && this.dataStore[j-this.gaps[g]] > this.dataStore[j]; j -= this.gaps[g]) {
swap(this.dataStore, j, j - this.gaps[g]);
}
//console.log(this.dataStore);
}
}
}
function shellsort1() {
var N = this.dataStore.length;
var h = 1;
while (h < N/3) {
h = 3 * h + 1;
}
while (h >= 1) {
for (var i = h; i < N; i++) {
for (var j = i; j >= h && this.dataStore[j] < this.dataStore[j-h]; j -= h) {
swap(this.dataStore, j, j-h);
}
//console.log(this.dataStore);
}
h = (h-1)/3;
}
}
function mergeArrays(arr,startLeft, stopLeft, startRight, stopRight) {
var rightArr = arr.slice(startRight, stopRight + 1);
var leftArr = arr.slice(startLeft, stopLeft + 1);
rightArr.push(Infinity);
leftArr.push(Infinity);
var m = 0;
var n = 0;
for (var k = startLeft; k <= stopRight; ++k) {
if (leftArr[m] <= rightArr[n]) {
arr[k] = leftArr[m];
m++;
} else {
arr[k] = rightArr[n];
n++;
}
}
//console.log("left array - ", leftArr);
//console.log("right array - ", rightArr);
}
function mergeSort() {
if (this.dataStore.length < 2) {
return;
}
var step = 1;
while (step < this.dataStore.length) {
var left = 0;
var right = step;
while (right + step <= this.dataStore.length) {
mergeArrays(this.dataStore, left, left + step - 1, right, right + step - 1);
left = right + step;
right = left + step;
}
if (right < this.dataStore.length) {
mergeArrays(this.dataStore, left, left + step - 1, right, this.dataStore.length - 1);
}
step *= 2;
}
}
function qSort(list) {
if (list.length <= 1) {
return list;
}
var lesser = [];
var greater = [];
var equal = [];
var pivotIndex = Math.floor(list.length / 2);
var pivot = list[pivotIndex];
for (var i = 0; i < list.length; i++) {
if (i == pivotIndex) {
continue;
}
if (list[i] < pivot) {
lesser.push(list[i]);
} else if (list[i] > pivot) {
greater.push(list[i]);
} else {
equal.push(list[i]);
}
}
return qSort(lesser).concat([pivot], equal, qSort(greater));
}
var numElements = 30000;
var reverseArray = new CArray(numElements);
function testSortingAlgorithms(array, name) {
console.log(`\n排序 ${name} 数组:`);
var arrays = [
{ name: '冒泡排序', method: 'bubbleSort' },
{ name: '选择排序', method: 'selectionSort' },
{ name: '插入排序', method: 'insertionSort' },
{ name: '希尔排序(固定间隔)', method: 'shellsort' },
{ name: '希尔排序(动态间隔)', method: 'shellsort1' },
{ name: '归并排序', method: 'mergeSort' },
{ name: '快速排序', method: 'qSort' }
];
arrays.forEach(({ name, method }) => {
var startTime = performance.now();
if (method === 'qSort') {
array.dataStore = qSort(array.dataStore.slice());
} else {
array[method]();
}
var endTime = performance.now();
console.log(`${name}: ${(endTime - startTime).toFixed(2)} 毫秒`);
});
}
testSortingAlgorithms(reverseArray, '倒序');
//排序 倒序 数组:
//冒泡排序: 939.10 毫秒
//选择排序: 314.90 毫秒
//插入排序: 775.60 毫秒
//希尔排序(固定间隔): 2.10 毫秒
//希尔排序(动态间隔): 1.70 毫秒
//归并排序: 10.70 毫秒
//快速排序: 14.10 毫秒
4. 创建一个包含 10 000 个随机整数的数组,使用快速排序和 JavaScript 内置的排序函数分 别对它进行排序,记录下它们的执行时间。这两种方法在执行时间上是否有区别?
function qSort(list) {
if (list.length <= 1) {
return list;
}
var lesser = [];
var greater = [];
var equal = [];
var pivotIndex = Math.floor(list.length / 2);
var pivot = list[pivotIndex];
for (var i = 0; i < list.length; i++) {
if (i == pivotIndex) {
continue;
}
if (list[i] < pivot) {
lesser.push(list[i]);
} else if (list[i] > pivot) {
greater.push(list[i]);
} else {
equal.push(list[i]);
}
}
return qSort(lesser).concat([pivot], equal, qSort(greater));
}
function builtInSort(array) {
return array.sort((a, b) => a - b);
}
function createRandomArray(numElements) {
var randomArray = [];
for (var i = 0; i < numElements; i++) {
randomArray.push(Math.floor(Math.random() * 1000000));
}
return randomArray;
}
var numElements = 30000;
var randomArray = createRandomArray(numElements);
function measureExecutionTime(sortFunction, array) {
var startTime = performance.now();
sortFunction(array);
var endTime = performance.now();
return endTime - startTime;
}
var quickSortCopy = [...randomArray];
var quickSortTime = measureExecutionTime(qSort, quickSortCopy);
console.log(`Quick Sort: ${quickSortTime.toFixed(2)} ms`);
var builtInSortCopy = [...randomArray];
var builtInSortTime = measureExecutionTime(builtInSort, builtInSortCopy);
console.log(`Built-in Sort: ${builtInSortTime.toFixed(2)} ms`);
//Quick Sort: 16.60 ms
//Built-in Sort: 9.20 ms
5万+

被折叠的 条评论
为什么被折叠?



