Skip to content

Commit 76fbc87

Browse files
author
朱安邦
committed
递归,插入排序,数组去重,筛选数据
1 parent 0087a27 commit 76fbc87

2 files changed

Lines changed: 189 additions & 26 deletions

File tree

JS算法原理/JS中的常见算法.md

Lines changed: 175 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99

1010
# 冒泡排序
1111

12-
基本思想:就是把数据像泡泡一样网上冒,让体积最轻的泡泡浮在最上面,然后按照重量往下依次排列;
12+
**基本思想**:就是把数据像泡泡一样网上冒,让体积最轻的泡泡浮在最上面,然后按照重量往下依次排列;
1313

14-
冒泡排序的操作原理:
14+
**冒泡排序的操作原理**
1515

1616
var ary=[11,2,31,45,6,78,37,33,21];
1717

@@ -78,3 +78,176 @@
7878
console.log(newAry);//[2, 6, 11, 21, 31, 33, 37, 45, 78]
7979

8080
# 快速排序;
81+
82+
**基本思想**:首先从数组ary选取一个基准点(通常我们取中间项作为基准点),然后遍历数组,把小于基准项放到基准点左边集合,把大于基准项放在基准点右边集合;然后对左边和右边两个集合分别再重复前面的操作;(直到每个集合就剩下一个元素的时候),其实就是一个**递归的思想**
83+
84+
**操作步骤**
85+
86+
var ary=[11,2,31,45,6,78,37,33,21];
87+
88+
依旧拿上边这个数组做例子,,我们确定一个基准点,
89+
90+
var ary=[11,2,31,45,6,78,37,33,21];
91+
var pivot=ary[Math.floor(ary.length/2)];
92+
console.log(pivot);//6
93+
94+
然后我们循环数据中的剩余项,把小于6的放在数组left中,把大于等于56的数组项放在数组right中,第一轮操作结束后left=[2],right=[11,31,45,78,37,33,21]
95+
96+
然后对left重复以上的操作,直到left和right仅剩一项或者空时候结束,最终返回left+pivot+right;
97+
98+
var ary=[11,2,31,45,6,78,37,33,21];
99+
100+
function quickSort(ary){
101+
var aryLen=ary.length;//获取ary的长度;
102+
if(aryLen<=1){//如果ary小于等于1的长度,就直接返回了;这一步非常重要,是判断是否循环完的标志;
103+
return ary;
104+
}
105+
var pINdex=Math.floor(ary.length/2);//基准项的所引值
106+
var pivot=ary.splice(pINdex,1);//删除基准项,并把基准项赋值给pivot;
107+
var left=[],right=[];
108+
for(var i= 0,len=ary.length;i<len;i++){
109+
if(ary[i]<pivot[0]){
110+
left.push(ary[i]);
111+
}else{
112+
right.push(ary[i])
113+
}
114+
}
115+
return quickSort(left).concat(pivot,quickSort(right));
116+
}
117+
var newAry=quickSort(ary);
118+
console.log(newAry);//[2, 6, 11, 21, 31, 33, 37, 45, 78]
119+
120+
# 插入排序
121+
122+
**操作步骤**:首先选取数组的第一项即ary[0],我们可以认为这个数是已经安排好序的,再取ary[1]项插入到已经排好序的元素中,此时只有ary[0],我们比较ary[0]和ary[1];大于ary[0]就放在后面,小于就插到ary[0]前面;要插入的元素依次为ary[1]至ary[ary.leng-1]项;插入到排序好的数组中的时候,插入每一项都需要从后面往前面遍历已经排序好的元素;**如果排序好的元素比插入的元素大,则把该元素往后挪一位,知道已经排序的元素小于等于要插入的元素(或者已经遍历完已经排好序的数组项),则把要插入的元素放在该位置+1的索引位置中(反向排的时候,需要放在数组的第0个位置)**,对每个插入的元素都执行上面的操作,最终数组就是排序好的;
123+
124+
有BUG的写法;
125+
126+
var ary=[11,2,31,45,6,78,37,33,21];
127+
128+
function insertSort(ary){
129+
var temp;//定义一个临时变量,保存要插入的值;
130+
for(var i= 1,len=ary.length;i<len;i++){
131+
if(ary[i]<ary[i-1]){
132+
temp=ary[i];
133+
ary[i]=ary[i-1];
134+
ary[i-1]=temp;
135+
}
136+
}
137+
return ary;
138+
}
139+
var newAry=insertSort(ary);
140+
console.log(newAry);//[2, 11, 31, 6, 45, 37, 33, 21, 78]
141+
142+
因为只把小的数往前移动了一次;这里需要用到while循环,把6移动2后面;
143+
144+
145+
var ary=[11,2,31,45,6,78,37,33,21];
146+
147+
function insertSort(ary){
148+
var temp;//定义一个临时变量,保存要插入的值;
149+
for(var i= 1,len=ary.length;i<len;i++){
150+
if(ary[i]<ary[i-1]){
151+
temp=ary[i];//需要插入的值;
152+
var pIndex=i-1;//需要插入值的前一个索引;
153+
while(temp<ary[pIndex]&&pIndex>=0){
154+
ary[pIndex+1]=ary[pIndex];//相当于ary[i]=ary[i-1];
155+
ary[pIndex]=temp;//相当于ary[i-1]=temp;完成一波交换;
156+
pIndex--;//准备下一波交换;
157+
}
158+
}
159+
}
160+
return ary;
161+
}
162+
var newAry=insertSort(ary);
163+
console.log(newAry);//[2, 6, 11, 21, 31, 33, 37, 45, 78]
164+
165+
# 数组去重;
166+
167+
- **第一种方法**:每一次拿出数组中的当前项和后面的所有项进行比较,如果相同的话,删除即可;
168+
169+
var ary=[1,2,34,56,6,7,45,3,2,2,12,4,9,8,6,7,4];
170+
function deleteRepeat(ary){
171+
for(var i= 0,len=ary.length-1;i<len;i++){//比较length-1次;
172+
var temp=ary[i];
173+
for(var j=i+1;j<ary.length;j++){
174+
if(temp==ary[j]){
175+
ary.splice(j,1);
176+
j--;//删除以后需要把j重置下,避免数组塌陷;
177+
}
178+
}
179+
}
180+
return ary;
181+
}
182+
var newAry=deleteRepeat(ary);
183+
console.log(newAry);
184+
185+
> 这种处理方法,处理少量数据的时候没有问题的,但是做很多数组的时候,性能就是一个很大的问题了,双重循环毕竟还是有优化的空间的,通常用第二种方法;
186+
187+
**第二种方法**:利用对象的属性名和属性值不能重复的原理,把数组中每一项的值当作对象的属性名属性值进行储存,在每一次储存之前进行判断,如果对象中已经存在这一项,我们就删除数组中这项,不存在我们就把这一项储存到我们的新的对象中,(注意对象在这里只是一个临时储存的作用),在处理完成后最好置为null;养成好习惯 ;
188+
189+
var ary=[1,2,34,56,6,7,45,3,2,2,12,4,9,8,6,7,4];
190+
function deleteRepeat(ary){
191+
var obj={};
192+
for(var i= 0,len=ary.length;i<len;i++){
193+
var temp=ary[i];
194+
if(obj[temp]==temp&&temp!=undefined){
195+
ary.splice(i,1);
196+
i--;
197+
continue;
198+
}
199+
obj[temp]=temp;
200+
}
201+
obj=null;
202+
return ary;
203+
}
204+
var newAry=deleteRepeat(ary);
205+
console.log(newAry);
206+
207+
# 从一个长度10万的数组中,随机取出100条数据(取出的数据不能重复);
208+
209+
原理:随机获取100个索引,每一次获取的时候,都把对应的项获取,为了避免数组中的项重复,每获取一个酒吧原有数组中的这一项删除;
210+
211+
为了方便掩饰从20个里取5个随机数;
212+
213+
第一种比较耗性能的写法;
214+
215+
var ary=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
216+
function selectOption(ary,optionNumber){
217+
var targetAry=[];
218+
if(!optionNumber){
219+
console.log("请指定需要删选的数量!");
220+
}
221+
for(var i=0;i<optionNumber;i++){
222+
var ran=Math.round(Math.random()*(ary.length-1));//获取0-数组最大索引的一个随机数;
223+
targetAry.push(ary[ran]);//按照获取的随机索引,把对应的值取出来,放到新书组中;
224+
ary.splice(ran,1);//数组中实现删除的时候比较耗性能,为了牵扯到数组长度的改变,数组被删除的项,后面所有数据都前进一位;
225+
}
226+
return targetAry;
227+
}
228+
var newAry=selectOption(ary,2);
229+
console.log(newAry);
230+
231+
> 确定在代码后面已经说明,这种的比较耗性能;
232+
233+
var ary=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
234+
function selectOption(ary,optionNumber){
235+
var targetAry=[];
236+
if(!optionNumber){
237+
console.log("请指定需要删选的数量!");
238+
}
239+
for(var i=0;i<optionNumber;i++){
240+
var ran=Math.round(Math.random()*(ary.length-1));//获取0-数组最大索引的一个随机数;
241+
targetAry.push(ary[ran]);//按照获取的随机索引,把对应的值取出来,放到新书组中;
242+
ary[ran]=ary[ary.length-1];//把数组最后一项放到当前要删除索引的这一项;
243+
ary.length=ary.length-1;//删除最后一项;
244+
}
245+
return targetAry;
246+
}
247+
var newAry=selectOption(ary,10);
248+
console.log(newAry);
249+
250+
> 这种的写法,是操作数组的常用处理方式;借助数组length可修改的性能;
251+
252+
253+

test-file.html

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,22 @@
1313
</div>
1414
<script>
1515

16-
var ary=[11,2,31,45,6,78,37,33,21];
17-
18-
function sortAry(ary){
19-
var aryLen=ary.length;//获取数组的长度;有aryLen个数在排序;
20-
var temp=null;//临时变量,交换数据中用的
21-
var flag=false;//设置标志位,初始化为false
22-
for(var i= 0,iLen=aryLen-1;i<iLen;i++){//外层循环n-1次;
23-
for(var j= 0,jLen=aryLen-1-i;j<jLen;j++){//每次循环完,都能从剩下的数组中找出个最大的数组放在aryLen-1-i的位置;
24-
if(ary[j]>ary[j+1]){
25-
temp=ary[j];
26-
ary[j]=ary[j+1];
27-
ary[j+1]=temp;
28-
flag=true;//如果交换好了,做个标记,避免无效的循环;
29-
}
30-
}
31-
if(!!flag){//只要交换了位置,flag的值就重新设置为false了;
32-
flag=false;
33-
}else{//如果没有交换,说明数组已经排好序了,可以结束循环了;
34-
break;
35-
}
16+
var ary=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
17+
function selectOption(ary,optionNumber){
18+
var targetAry=[];
19+
if(!optionNumber){
20+
console.log("请指定需要删选的数量!");
21+
}
22+
for(var i=0;i<optionNumber;i++){
23+
var ran=Math.round(Math.random()*(ary.length-1));//获取0-数组最大索引的一个随机数;
24+
targetAry.push(ary[ran]);//按照获取的随机索引,把对应的值取出来,放到新书组中;
25+
ary[ran]=ary[ary.length-1];//把数组最后一项放到当前要删除索引的这一项;
26+
ary.length=ary.length-1;//删除最后一项;
3627
}
37-
return ary;
28+
return targetAry;
3829
}
39-
40-
var newAry=sortAry(ary);
41-
console.log(newAry);//[2, 6, 11, 21, 31, 33, 37, 45, 78]
30+
var newAry=selectOption(ary,10);
31+
console.log(newAry);
4232

4333
</script>
4434
</body>

0 commit comments

Comments
 (0)