冒泡排序比较所有相邻的两个项,如果第一个比第二个大,则交换它们。元素项向上移动至正确的顺序,就好像气泡升至表面一样,冒泡排序因此得名。
//一维数组冒泡排序,从大到小
let testArray = [77, 41, 31, 43, 11, 33, 21];
for (let i = 0; i < testArray.length - 1; i++) {
for (let j = 0; j < testArray.length - 1; j++) {
if (testArray[j] > testArray[j + 1]) {
//冒泡,交换相邻数据元素
let t = testArray[i];
testArray[i] = testArray[i + 1];
testArray[i + 1] = t;
}
}
}
document.write(testArray);
如果从内循环减去外循环中已跑过的轮数,就可以避免内循环中所有不必要的比较.
//一维数组改进冒泡排序,从大到小
let testArray = [77, 41, 31, 43, 11, 33, 21];
for (let i = 0; i < testArray.length - 1; i++) {
for (let j = 0; j < testArray.length - 1 - i; j++) {
if (testArray[j] > testArray[j + 1]) {
let t = testArray[i];
testArray[i] = testArray[i + 1];
testArray[i + 1] = t;
}
}
}
document.write(testArray);
选择排序算法是一种原址比较排序算法。选择排序大致的思路是找到数据结构中的最小值并
将其放置在第一位,接着找到第二小的值并将其放在第二位,以此类推。
//一维数组选择排序,从小到大
let testArray = [77, 41, 31, 43, 11, 33, 21];
let indexMin;
//交换数据元素
function swap(array,i,j){
let t = array[i];
array[i]=array[j];
array[j]=t;
}
for (let i = 0; i < testArray.length - 1; i++) {
indexMin = i;
//选择未排序的元素中最小的元素
for (let j = i; j < testArray.length; j++) {
if (testArray[i] > testArray[j])
indexMin = j;
}
if (i !== indexMin) {
swap(testArray, i, indexMin);
}
}
document.write(testArray);
每次确定一个数据元素的位置,将该数据元素插入的该数据元素下标之前已经排好序的子序列的正确位置上。
//一维数组直接插入排序,从小到大
let testArray = [77, 41, 31, 43, 11, 33, 21];
let temp,i,j;
for (i = 1; i < testArray.length; i++) {
//如果当前元素比前面的元素小,则遍历前面的元素,把当前元素插入到正确的位置,待插入位置至当前元素初始位置前一个元素后移一位
if(testArray[i]<testArray[i-1]){
temp=testArray[i];
//如果当前选择的元素比遍历的元素小则停止循环
for(j=i-1;temp<testArray[j];--j){
testArray[j+1]=testArray[j];
}
testArray[j+1]=temp;
}
}
document.write(testArray);
排序小型数组时,此算法比选择排序和冒泡排序性能要好。
快速排序也许是最常用的排序算法了。它的复杂度为 O(nlog(n)),且性能通常比其他复杂度
为 O(nlog(n))的排序算法要好。
//一维数组快速排序,从小到大
var testArray = [77, 41, 31, 43, 11, 33, 21];
//递归
function quickSort(arr, left, right) {
if (left < right) {
var pivotpos = partition(arr, left, right);
quickSort(arr, left, pivotpos - 1);
quickSort(arr, pivotpos + 1, right);
}
return arr;
}
//划分
function partition(arr, left, right) {
let pivot = left,index = pivot;
for (let i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
swap(arr, i, index);
index++;
}
}
swap(arr, pivot, index - 1);
return index;
}
//交换
function swap(array, i, j) {
let t = array[i];
array[i] = array[j];
array[j] = t;
}
//输入数组,参与排序的起始位置和终止位置
testArray = quickSort(testArray, 0, testArray.length - 1);
document.write(testArray);
我们用最大堆得到一个升序排列的数组(从最小到最大)。如果我们想要这个数组按降序排列,可以用最小堆代替。
let testArray = [77, 41, 31, 43, 11, 33, 21];
function heapSort(array) {
let heapSize = array.length;
buildMaxHeap(array); // 步骤 1
while (heapSize > 1) {
swap(array, 0, --heapSize); // 步骤 2
heapify(array, 0, heapSize); // 步骤 3
}
return array;
}
function buildMaxHeap(array) {
for (let i = Math.floor(array.length / 2); i >= 0; i -= 1) {
heapify(array, i, array.length);
//document.write(testArray);
}
return array;
}
function heapify(arr, index, length) {
var left = 2 * index + 1,
right = 2 * index + 2,
largest = index;
if (left < length && arr[left] > arr[largest]) {
largest = left;
}
if (right < length && arr[right] > arr[largest]) {
largest = right;
}
if (largest !== index) {
swap(arr, index, largest);
heapify(arr, largest, length, );
}
}
function swap(arr, i, j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
testArray = heapSort(testArray);
document.write(testArray);
顺序或线性查找是最基本的查找算法。它的机制是,将每一个数据结构中的元素和我们要找
的元素做比较。顺序搜索是最低效的一种查找算法。
//一维数组顺序查找
var testArray = [77, 41, 31, 43, 11, 33, 21];
var key = 31;//查找关键字
function seqSearch(arr,e){
for(let i=0;i<arr.length;i++){
if(arr[i]===e){
return i+1;
}
}
return 0;
}
var index = seqSearch(testArray,key);
if(index){
document.write(key,"是第",index,"个元素");
}else{
document.write("查找失败");
}
二分查找又称折半查找,仅适用于有序的顺序表
//一维数组二分查找
var testArray = [77, 41, 31, 43, 11, 33, 21];
let key = 31;
function compare(a, b) {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
function binarySearch(arr, e) {
var left = 0, right = arr.length - 1, mid;
while (left <= right) {
mid = (left + right) / 2;
if (arr[mid] === e) {
return mid + 1;
} else if (arr[mid] > e) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return 0;
}
//sort 方法在对数组做排序时,把元素默认成字符串进行相互比较,我们要传入自己写的比较行数。
//排序
testArray.sort(compare);
document.write(testArray,"
");
var index = binarySearch(testArray, key);
if (index) {
document.write(key, "是第", index, "个元素");
} else {
document.write("查找失败");
}
插值查找:根据查找关键字与查找表中最大最小记录关键字比较后的查找方法。插值查找基于二分查找,将查找点的选择改进为自适应选择,提高查找效率。
将二分查找的点改进为 mid = left+(e-arr[left])/(arr[right]-arr[left])*(right-left);
时间复杂度:O(log₂(log₂n))
应用:对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多
//一维数组插值查找
var testArray = [77, 41, 31, 43, 11, 33, 21];
let key = 43;
function compare(a, b) {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
function insertSearch(arr,e){
var left = 0, right = arr.length - 1;
while (left <= right) {
var mid = left+(e-arr[left])/(arr[right]-arr[left])*(right-left);
mid = Math.round(mid);
if (arr[mid] === e) {
return mid + 1;
} else if (arr[mid] > e) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return 0;
}
testArray.sort(compare);
document.write(testArray, "
");
var index = insertSearch(testArray, key);
if (index) {
document.write(key, "是第", index, "个元素");
} else {
document.write("查找失败");
}