数组的算法
冒泡排序
一种较为简单的排序算法,它会重复的走访需要排序的数列,每一次比较两个元素,如果它们的顺序错误就会被调转过来,从而达到正确排序的作用,最后的结果就会呈现按照一定规律(从大到小/从小到大)排序的现象。
特点:
1,如果有n个数字,则需要排序n-1轮
2,每一轮都需要比较n-i次,i表示第几轮
/*
冒泡排序:
总共需要 arr.length-1 轮
每一轮需要比较 arr.length-当前轮数(轮数从1开始)
*/
var arr = [12,2,190,64,56,63,29];
for( var i=0;i<arr.length;i++ ){// 外层循环控制轮数
for( var j=0;j<arr.length-i;j++ ){// 内层循环控制每一轮的次数
if( arr[j]<arr[j+1] ){ // 升序
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
console.log( arr );//[190, 64, 63, 56, 29, 12, 2]
for(let i = 0 ;i <arr.length;i++){
for(let j =0;j <arr.length-i;j++){
if(arr[j]>arr[j+1]){
let temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
console.log(arr);// [2, 12, 29, 56, 63, 64, 190]
二分法查找
二分法查找适用于数据量较大时,但是数据需要先排好顺序。
具体思路:
要求数组必须是有序的。
将查找的项目和数组的中间的值比较,如果大取右边,如果小取左边,这样就可以一次性筛选掉一半的数据。
再次查找,还是和剩余的一半的中间值比较,再次帅选掉一半
重复执行,最终找到结果。
需求:封装一个函数,查找某一个元素是否存在数组中,如果存在就返回索引,如果不存在就返回-1。
// 二分法:要求数组必须是有序的
var arr = [1,23,34,45,56,67,78,89,90,100,101,102,156,178,209];
function erfen(arr,ele){
// 定义最小索引
var minIndex = 0
// 定义最大索引
var maxIndex = arr.length-1;
// 算出中间索引
var midIndex = (minIndex+maxIndex)/2
// 判断条件
while( minIndex<=maxIndex ){
if( arr[midIndex] === ele ){
return midIndex;
}else if( ele>arr[midIndex] ){
// 更新最小索引
minIndex = midIndex+1;
}else{
// 更新最小索引
maxIndex = midIndex-1;
}
// 更新中间索引
midIndex = (minIndex+maxIndex)/2
}
return -1;
}
var index = erfen(arr,178);
console.log(index);
function erfen(arr,num){
let minIndex=0;
let maxIndex = arr.length-1;
let midIndex = (minIndex +maxIndex)/2
while(minIndex <= maxIndex){
if(arr[midIndex] === num){
return midIndex;
}else if(midIndex < num){
minIndex = midIndex+1;
}else{
maxIndex =midIndex -1;
}
midIndex = (minIndex +maxIndex)/2
}
return -1
}
let result = erfen(arr,3);
console.log(result);
数组去重
程序可能会需要一个元素值相对唯一的数组,这样我们就需要将数组中重复的值剔除出去。
// 数组去重
var arr = [11,2,2,2,'hello','world','hello'];
// 新建一新数组,遍历传入数组,值不在新数组就push进该新数组中
var newArr = [];
for( var i=0;i<arr.length;i++ ){
if( !newArr.includes( arr[i] ) ){
newArr.push(arr[i])
}
}
console.log( newArr );//[11, 2, "hello", "world"]
//方法2
for(let i =0 ; i <arr.length;i++){
if(!newArr.includes(arr[i])){
newArr[newArr.length] = arr[i]
}
}
console.log( newArr );//[11, 2, "hello", "world"]
数组求差集/交集/并集
思路:利用indexOf或者includes方法。
var arr1 = [1,2,3];
var arr2 = [2,3,4,5];
var arr3 = [];
//并集 arr3 = [1,2,3,4,5]
//思路:合并数组,再去重
function bing(arr1,arr2){
var arr4 = arr1.concat(arr2);
for(var i = 0; i<arr4.length;i++){
//如果在arr3中找不到arr4的值,就把arr4的值push进arr3
if( arr3.indexOf(arr4[i])){
arr3.push(arr4[i])
}
}
return arr3
}
var result = bing(arr1,arr2)
console.log(result);//[1, 2, 3, 2, 3, 4, 5]
//交集 arr3 = [2,3]
//思路:返回两个数组相同的数
arr3 = arr1.filter(function(num) {
return arr2.indexOf(num) !== -1;
});
console.log(arr3);//[2, 3]
//差集 arr3 = [1,4,5]
//思路,合并数组,筛选arr3
arr3 = arr1.concat(arr2).filter(function(num) {
return !arr1.includes(num) || !arr2.includes(num)
});
console.log(arr3);//[1,4,5]
基本数据类型和引用数据类型区别
// 基本数据类型
var n1 = 10;
var n2 = n1;
n2 = 20;
console.log( n1 );// 10
console.log( n2 );// 20
// 引用数据类型
var arr1 = [1,2,3];
var arr2 = arr1;
arr2.push( 4 );
console.log( arr1 );// [1,2,3,4]
console.log( arr2 );// [1,2,3,4]
console.log( arr1 === arr2 );
练习2
// 1. 三个算法:冒泡,二分,去重
//2.冒泡:如果有n个数字,则需要排序n-1轮,每一轮都需要比较n-i次,i表示第几轮
//3.封装一个函数,查找某一个元素是否存在数组中,如果存在就返回索引,如果不存在就返回-1。
//4.程序可能会需要一个元素值相对唯一的数组,这样我们就需要将数组中重复的值剔除出去。新建一新数组,遍历传入数组,值不在新数组就push进该新数组中
答案2
//冒泡
var arr = [34,12,45,33,99,1]
//方法1 普通排序
//确定几轮,确定每轮比较次数
for(var i = 0; i <arr.length; i++){
//每个数字都要比较n-i次
for(var j = 0; j < arr.length - i ; j++){
if(arr[j] > arr[j+1]){//升序
//交换
var temp;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp
}
}
}
// console.log(arr);//[1, 12, 33, 34, 45, 99]
//方法2 函数实现,实现一次封装,多次调用
var arr1 = [22,14,33,23,67,34]
var arr2 = [43,11,23,65]
//封装函数
function upSort(xx){
//复制上述代码
for(var i = 0; i <xx.length; i++){
//每个数字都要比较n-i次
for(var j = 0; j < xx.length - i ; j++){
if(xx[j] > xx[j+1]){//升序
//交换
var temp;
temp = xx[j];
xx[j] = xx[j+1];
xx[j+1] = temp
}
}
}
console.log(xx);
}
upSort(arr1)//[14, 22, 23, 33, 34, 67]
upSort(arr2)//[11, 23, 43, 65]
//方法3 自定义方法实现
// 函数和方法的区别?
// 函数:是独立存在的函数 通过fn()调用
// 方法:是属于对象的函数,方法也是函数,是特殊的函数,通过dog.bark()调用
//括号左边是函数,‘.’的右边是方法
//先构造函数
Array.prototype.upSort2 = function(){
var xx =[]
//构造函数中的this指向了将来被创建的对象,即arr3,arr4
for(var i = 0; i <this.length; i++){
//每个数字都要比较n-i次
for(var j = 0; j < this.length - i ; j++){
if(this[j] > this[j+1]){//升序
//交换
var temp;
temp = this[j];
this[j] = this[j+1];
this[j+1] = temp
}
}
}
xx = this
return xx
}
var arr3 = [99,11,22,33]
var arr4 = [113,23,43]
console.log( arr3.upSort2() ); // [11, 22, 33, 99]
console.log( arr4.upSort2() ) //[23, 43, 113]
//封装一个函数,查找某一个元素是否存在数组中,如果存在就返回索引,如果不存在就返回-1。
// 方法1:封装函数
var arr = [32,12,45];
// console.log( arr.indexOf(11) );//-1
function search(arr,x){
//遍历数组
for(var i = 0; i < arr.length; i++){
if(arr[i] === x){
return i
}
}
return -1
}
// search(arr,32)
console.log( search(arr,45) );
//方法2:自定义方法
Array.prototype._indexOf = function(value){
for(var i=0; i<this.length; i++){
if(this[i] == value){
return i;
}
}
return -1;
}
var arr = [1,2,3,4];
console.log(arr._indexOf(3));
//4.程序可能会需要一个元素值相对唯一的数组,这样我们就需要将数组中重复的值剔除出去。新建一新数组,遍历传入数组,值不在新数组就push进该新数组中
var arr = [3,4,2,3,3]
var new_arr = []
//遍历
for(var i = 0; i < arr.length;i++){
//新数组如果没有值和原数组的值相等,就将原数组的值放入新数组
if( new_arr.indexOf(arr[i]) ){
new_arr.push(arr[i])
}
}
console.log(new_arr);//[3, 4, 2]