2010-12-29 2 views
1

라이브 코드 : http://jsfiddle.net/fCUZC/누군가이 자바 스크립트 코드가 배열을 순서대로 나열하지 않는 이유를 말해 줄 수 있습니까?

//INPUT ARRAY: 
var input = [28,32,21,11,8,2,14,32,64]; 
//VARIABLE DECLARATION. a = highest number so far, b = position of that number 
entireLoop: 
for (var i = 1; i<=input.length; i++) 
{ 
    if(input[i] > input[i-1]) 
    { 
     for(var o = i; o>=0; o--) 
     { 
      if(input[i-1] > input[o]) 
      { 
       input.splice(i,0,input[o]); 
       input.splice((o+1),1); 
       continue entireLoop; 
      } 
      else if(input[o] > input[0]) 
      { 
       input.splice(0,0,input[o]); 
       input.splice((o+1),1); 
       continue entireLoop; 
      } 

     } 
    } 
} 
document.write(input); 

나는 가장 큰에서 최소의 배열을 주문하기 위해 노력하고있어,하지만 어딘가에 붙어 (32)이있다. 정렬 방법이 있다는 것을 알고 있지만, 나는 초보자이며 이것을 직접 해보고 싶습니다.

+1

이것이 어떤 정렬 알고리즘이라고 생각하십니까? 귀하의 알고리즘 설계에 대한 일반적인 문제와 같이 보입니다. – Simon

+2

이 알고리즘은 발명입니까 구현입니까? 꽤 배고파 보이는군요 ... –

+0

숫자가 중복되고 나머지 숫자가 누락되었습니다 (중복 2 및 누락 14) ... 끝 부분의 32보다 훨씬 나쁨) –

답변

5

** ** ** 먼저 배열의 원시 .sort() 메소드를 살펴보십시오. 원본 배열은 그대로두고 비교 기능을 허용합니다. 후자는 .sort()를 매우 강력하게 만듭니다.

var input = [28,32,21,11,8,2,14,32,64]; 

var low2high = function (a , b) { 
    return a > b; 
}; 

var high2low = function (a , b) { 
    return a < b; 
}; 

var resultHigh2low = input.sort(high2low); // [ 64,32,32,28,21,14,11,8,2 ]; 
var resultLow2high = input.sort(low2high); // [ 2,8,11,14,21,28,32,32,64 ]; 

그래서 우리는 우리가 다음 쓸 수 있습니다 (OP 주석을 참조 TJ 크라우에서 제공하는 링크) 거품 정렬을 사용하려는 경우 :

var bubbleSort = function (list , comparison) { 
    ..code.. 
} 
:

// javascript bubbleSort implementation 
var bubbleSort = function (list , comparison) { 
    var swapped; 
    var i; 
    var val; 

    list = [].concat(list); // do not destroy original 
    comparison = (typeof comparison == "function") ? comparison : function(a,b){return a > b;} 

    do { 
     i = list.length; 
     while (--i) { 
      if (i && comparison(list[ i ] , comparison[ i-1])) { 
       val = list[ i ]; 
       list[ i ] = list[ i - 1 ]; 
       list[ i - 1] = val; 
       swapped = true; 
      } 
     } 
    } while (swapped); 
    return list; 
} 

// using comparison functions from previous example. 
var resultHigh2low = bubbleSort(input , high2low); // [ 64,32,32,28,21,14,11,8,2 ]; 
var resultLow2high = bubbleSort(input , low2high); // [ 2,8,11,14,21,28,32,32,64 ]; 

은 단계적으로 그것을 통해 걸을 수 있습니다을

우리의 함수는 2 개의 매개 변수를 받아들입니다. 첫 번째는 배열이고, 두 번째는 선택적 비교 함수입니다.

var swapped; 
var i = list.length; 
var val; 

우리는 변수 i 아래의 목록의 길이를 저장하고, 우리가 나중에 사용하려고하고 2 개 빈 변수 (swappedval)를 선언합니다.

list = [].concat(list); // do not destroy original 

우리는 [].concat(array)를 사용하여 목록을 복제하고 원본 그대로를 떠나 지역 list 변수를 덮어 씁니다. 그것은 function은 우리가 하나를 사용의 경우

comparison = (typeof comparison == "function") ? comparison : function(a,b){return a > b;} 

우리는 그렇지 않으면 우리는 우리 자신의 comparison 기능을 다시 하강의 typeof comparison 인수를 테스트합니다. ab보다 큰 경우 폴백 비교 함수는 true을 반환합니다.

do { 
    ..code.. 
} while (swapped); 

A는 루프가 적어도 한 번에 실행하는 동안, 우리 swapped 변수가 현재 그래서 falsy으로 해석됩니다 undefined입니다/않습니다. comparison 함수가 true를 반환하면 스왑이 발생하고 swapped 변수가 true로 설정되어 다시 반복됩니다. 여기

while (--i) { 
    ..code.. 
} 

아래 목록의 길이에서 나는 루프는 -- 운영자가 처음 아무것도하기 전에, i--while 평가가 존재하지 않는 list[ list.length ] 이후 erronous 결과를 야기 후에 터질 것 처리 보장하기 위해 i 변수 앞에 배치됩니다. 나는 항상 이런 식으로 (아마도 나쁜 습관),하지만 그것이 당신을 혼란스럽게한다면 절대적인 투명성으로 나아가십시오.

if (i && comparison(list[ i ] , comparison[ i-1])) { 
    ..code.. 
} 

먼저 우리는 i truthy 값을 갖는 경우 (0을 평가하여하기 falsy) 확인한 후 우리 ab 파라미터로서 list[ i ]list[ i - 1 ] 지나가는 comparison 기능을 실행. comparison 함수가 true을 반환하면 스왑을 수행합니다.

val = list[ i ]; 
list[ i ] = list[ i - 1 ]; 
list[ i - 1] = val; 
swapped = true; 

은 여기가 .splice() 방법을 사용하지 않고 스왑을 수행, 그것은. 단지 추측의 기압,하지만 직접 과제를 파악 빠른 함수 호출 후입니다. 자리 표시 자로 val 변수를 사용합니다. 스왑이 완료된 후 swapped을 true로 설정하여 do/while 루프가 계속됩니다.

return list; 

음 ... 결과를 반환하십시오.

일부 검사를 제외했습니다. 목록의 길이가 0이고 그 밖의 것이 아닌 경우 어떻게해야합니까? 기본적으로 도우미 함수를 작성할 때 오류 처리를 처리해야합니다. 전달 된 비교 인수가 함수가 아닌 경우 TypeError를 던지는 것과 마찬가지로 비교 메서드가 부울 값을 반환하는지 확인하는 등의 작업을 수행합니다.

+0

좋은 답변. 각 루프를 재설정하지 않아도 되나요? 당신은 i = list length에서 0으로 내려 갔지만 그때는 보이지 않습니다. 다음 루프를 위해 그것을 다시 설정합니다. 그게 당신이 놓친 줄이나 내가 뭔가를 놓치고 있습니까? 또한 "진실"및 "위조":) – Chris

+0

예치, oopsy, 좋은 catch;) – BGerrissen

2
//INPUT ARRAY: 
var input = [28,32,21,11,8,2,14,32,64]; 
//VARIABLE DECLARATION. a = highest number so far, b = position of that number 
for (var i = 1; i<input.length; i++) 
{ 
    if(input[i] > input[i-1]) 
    { 
     for(var o = i-1; o>=0; o--) 
     { 
      if(input[i] > input[o]) 
      { 
       input.splice(i+1,0,input[o]); 
       input.splice((o),1); 
       i--; 
      }  
     } 
    } 
} 
document.write(input); 

여전히 좋지는 않지만 작동해야합니다. 내가 이걸 간신히 테스트 한 것을 염두에 두라. 나는 자바 스크립트에 익숙하지 않다. 당신의 의도는 모두 나쁘지 않았으며 모두가 어딘가에서 시작해야합니다.

가장 큰 문제는 내부 조건 일뿐입니다. 내가 찾은 큰 가치에서 거꾸로 반복하고 모든 작은 값을 오른쪽으로 밀어내는 논리를 볼 수 있습니다. 불행히도 귀하의 색인은 조금 벗어났습니다. 계속 진행하지 않고 정상적으로 완료 될 때까지이 루프를 실행해야합니다. 그렇지 않으면 한 값만 전환됩니다. 이 조건부가 고정되면 두 번째 것은 더 이상 필요하지 않습니다.

대체 양식은 가장 낮은 색인부터 시작하여 input [i]보다 작은 첫 번째 값을 찾아서 배치하는 것입니다. 이것은 잠재적으로 명확합니다.

나는 이것이 꽤 좋은 첫발이었고 일하기가 열심히 아니었다 고 생각한다. 행운을 빕니다!

+0

것 같습니다 시도한 테스트 입력에 대한 매력. 잘 했어. :) – Chris

관련 문제