数据结构与算法JavaScript描述练习------第12章排序算法

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值