排序算法:
1. 冒泡排序
冒泡排序通过比较相邻两个值的大小进行两两比较,顺序相反,则交换两者位置。这样,每一趟会将最小或最大的元素浮到末尾位置。
//冒泡排序
function bubbleSort(array){
var temp;
for (var i = 0; i < array.length - 1; i++){
for (var j = 0; j < array.length-1-i; j++){
if (array[j]>array[j+1]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
return array;
}
外圈表示执行的趟数,每执行一趟就可以确定一个最大值或最小值。内圈表示两两进行比较的次数。
冒泡排序的时间复杂度计算过程:循环次数为(n-1)+(n-2)+(n-3)+…+1=(n-1)n/2。所以时间复杂度为O(n^2)。
其实这个程序还可以更简单,我们考虑,当循环完一趟之后,发现排序完的数组跟之前的数组没有变化,就说明这时已经排序好了。
因此,程序更改为:
function bubbleSort(array){
var temp;
for (var i = 0; i < array.length - 1; i++){
var flag = false; //加一个标记,若执行完一趟之后结果没有改变,就说明已排序完成,则跳出循环。
for (var j = 0; j < array.length-1-i; j++){
if (array[j]>array[j+1]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flag = true;
}
}
if(!flag){
break;
}
}
return array;
}
2.简单选择排序
简单选择排序就是每趟通过比较所有元素的值,选出最小的元素放到首位。看程序
用min来记录当前趟中最小值的位置,找到最小值的位置之后,再进行交换。
//简单选择排序
function selectSort(array){
for (var i = 0; i < array.length-1; i ++){
var min = i,
temp;
for (var j = i + 1; j < array.length; j ++){
if (array[j] < array[min]){
min = j;
}
}
temp = array[i];
array[i] = array[min];
array[min] = temp;
}
return array;
}
计算复杂度:(n-1)+(n-2)+(n-3)+…+1=n(n-1)/2,时间复杂度为O(n^2)
3. 直接插入排序
function insertSort(array){
for (var i = 1; i < array.length; i++){
if(array[i] < array[i-1]){
//array[i]值和array[i]之前的值比较并移位
var temp = array[i]; //保存第i位的值
var k = i-1;
for (var j = k; j >= 0 && temp < array[j]; j --){
array[j+1] = array[j];
k--;
}
array[k+1] = temp; //插入正确的位置
}
}
return array;
}
4. 希尔排序
希尔排序就是将待排序序列分成几个子序列,分别再进行直接插入排序。
//希尔排序
function shellSort(array){
var gap = 1,
len = array.length,
temp;
while(gap<len/3){
gap = gap * 3 + 1; //动态定义间隔序列
}
for(gap; gap > 0; gap = Math.floor(gap / 3)){ //根据gap值确定循环趟数,直到gap=0时循环停止
for (var i = gap; i < len ; i++){
temp = array[i];
for (var j = i - gap; j>=0&&temp<array[j]; j-=gap){
array[j+gap] = array[j] ;
}
array[j+gap] = temp;
}
}
return array;
}
查找算法
1.顺序查找
function sequentialSearch(array,n){
for (var i = 0; i < array.length; i++){
if (array[i] === n){
return i;
}
}
return -1; //没有找到
}
执行次数为n次,所以时间复杂度为O(n)
2.二分查找
二分查找(又称为折半查找)是在有序序列中查找比较多的查找算法,基本思路:设有一个从小到大的序列,取中间的元素m进行比较,如果等于需要查找的元素x则返回元素m的下标,若x大于m则再从右边的区间查找,若x小于m则再从左边的区间查找,这样每次减少一半的查找范围。时间复杂度为O(log2(n)),查找速度相对顺序查找要快很多,但是查找的数据序列必须是有序序列(即数据是从小到大或从大到小排序的)。
function binarySearch(array,n){
var left = 0,
right = array.length - 1,
mid = Math.floor((left+right)/2);
while(left<=right){
if(array[mid] === n){
return mid;
}else if(array[mid] > n){
right = mid - 1;
}else{
left = mid + 1;
}
}
return -1;
}
3.插值查找
基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。
注:对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。反之,数组中如果分布非常不均匀,那么插值查找未必是很合适的选择。
function interpolationSearch(array,n){
var left = 0,
right = array.length - 1,
mid;
while(left<=right){
mid = Math.floor(left+((n-array[left])/(array[right]-array[left]))*(right-left));
if(array[mid] === n){
return mid;
}else if(array[mid] > n){
right = mid - 1;
}else{
left = mid + 1;
}
}
return -1;
}
package com.chehejia.esdqa.cclientautotest.testcase.aisp_aggregation_api.car_state;
import lombok.extern.slf4j.Slf4j;
/**
* @author wangliyuan
* @date 2021/9/1 11:10
*/
@Slf4j
public class MyTest {
public static int[] arr = new int[]{6, 5, 4, 10, 8, 3};
public static int[] arr1 = new int[]{3, 4};
public static int[] bubbleSort(int[] arr){
int len = arr.length;
for(int i = 0; i < len; i ++){
int temp;
int lastSwap = 0;
for(int j = 0; j < len - i -1; j++){
if(arr[j + 1] < arr[j]){
temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
lastSwap ++;
}
}
if(lastSwap == 0){
break;
}
}
return arr;
}
//直接选择排序
public static int[] straightSelectSort(int[] arr){
int len = arr.length;
for(int i = 0; i < len-1; i ++){
int min = i;
int temp;
for (int j = i + 1; j < len; j++){
if(arr[j] < arr[min]){
min = j;
}
}
if(min != i){
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
return arr;
}
//直接插入排序
public static int[] straintInsertSort(int[] arr){
int len = arr.length;
for (int i = 1; i < len; i++){
int j = i - 1;
int temp = arr[i];
while (j >=0 && arr[j] > temp){
arr[j + 1] = arr[j];
j = j -1;
}
arr[j + 1] = temp;
}
return arr;
}
//快速排序
public static int partition(int[] arr, int left, int right){
int temp = arr[left]; //基准值
while(left < right){
while(arr[right] >= temp && right > left){
right --;
}
if(right > left){
arr[left] = arr[right];
}
while(left < right && arr[left] <= temp){
left ++;
}
if(left < right){
arr[right] = arr[left];
}
}
arr[left] = temp;
return left;
}
public static int[] quickSort(int[] arr, int left, int right){
if(left < right){
int partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex - 1);
quickSort(arr, partitionIndex + 1, right);
}
return arr;
}
//堆排序
public static int[] heapSort(int[] arr){
int len = arr.length;
for(int i = len-1; i > 0; i --){
sort(arr,0, i);
}
return arr;
}
public static void sort(int[] arr, int startIndex, int endIndex){
int index = startIndex + 1;
while(index <= endIndex){
//父节点 (i-1)/2
//左节点 i * 2 + 1
//右节点 i * 2 + 2
int fatherNodeIndex = (index - 1)/2;
if(arr[index] > arr[fatherNodeIndex]){
int temp = arr[index];
arr[index] = arr[fatherNodeIndex];
arr[fatherNodeIndex] = temp;
}
index ++;
}
//大顶堆获取第一个值和最后一个值交换位置
int temp = arr[endIndex];
arr[endIndex] = arr[0];
arr[0] = temp;
}
//希尔排序
public static int[] xierSort(int[] arr){
int len = arr.length;
int gap = len/2;
while(gap > 0){
for(int i = gap; i < len; i++){
int j = i - gap;
int temp = arr[i];
while(j >= 0 && arr[j] >temp){
arr[j + gap] = arr[j];
j-=gap;
}
arr[j + gap] = temp;
}
gap = gap / 2;
}
return arr;
}
public static void main(String[] args) {
xierSort(arr);
}
}