Quick select partitioning









up vote
0
down vote

favorite












I am trying to understand how QuickSelect partitioning works, and there are a few things I don't get, I will try to explain how I see it (please notice that I have renamed the variables and made my comments to try to understand it, so maybe some renaming or commenting is wrong):



  • First, the value of the pivot is the value of the index the pivot is at, that makes sense.

  • We now swap the pivot to the end of the Array, why?

  • We have a first pointer which starts at left, because the first pointer should of course start at the start.

  • In the for loop we have a second pointer, which also starts at left, why?. Shouldn't it start at the other end?

  • If where we are at is less than the pivot value, swap them, so we get the lesser elements to the left.

  • At the end swap the pivot back (this leads to my fist "why").

  • At the end we return the first pointer, which I assume is because that is the only element left in the Array?

I have seen different kinds of implementations, and I have found that most if not all do this.



// Partitioning.
private static int quickSelectPartition(int array, int left, int right, int pivotIndex)
// The value of the pivot depends on the value at the random index that we got.
int pivotValue = array[pivotIndex];

// Move the pivot to the end.
swapLeftWithRight(array, pivotIndex, right);

// First pointer starts from left.
int firstPointer = left;

// Second pointer starts from left.
for(int secondPointer = left; secondPointer < right; secondPointer++)

// If the value at the second pointer is less than pivot value, swap it to where the first pointer is.
if(array[secondPointer] < pivotValue)

// Swap.
swapLeftWithRight(array, firstPointer, secondPointer);

// Move the first pointer forward.
firstPointer++;



// When done with this partitioning, swap the pivot back to its original position.
swapLeftWithRight(array, right, firstPointer);

return firstPointer;










share|improve this question

























    up vote
    0
    down vote

    favorite












    I am trying to understand how QuickSelect partitioning works, and there are a few things I don't get, I will try to explain how I see it (please notice that I have renamed the variables and made my comments to try to understand it, so maybe some renaming or commenting is wrong):



    • First, the value of the pivot is the value of the index the pivot is at, that makes sense.

    • We now swap the pivot to the end of the Array, why?

    • We have a first pointer which starts at left, because the first pointer should of course start at the start.

    • In the for loop we have a second pointer, which also starts at left, why?. Shouldn't it start at the other end?

    • If where we are at is less than the pivot value, swap them, so we get the lesser elements to the left.

    • At the end swap the pivot back (this leads to my fist "why").

    • At the end we return the first pointer, which I assume is because that is the only element left in the Array?

    I have seen different kinds of implementations, and I have found that most if not all do this.



    // Partitioning.
    private static int quickSelectPartition(int array, int left, int right, int pivotIndex)
    // The value of the pivot depends on the value at the random index that we got.
    int pivotValue = array[pivotIndex];

    // Move the pivot to the end.
    swapLeftWithRight(array, pivotIndex, right);

    // First pointer starts from left.
    int firstPointer = left;

    // Second pointer starts from left.
    for(int secondPointer = left; secondPointer < right; secondPointer++)

    // If the value at the second pointer is less than pivot value, swap it to where the first pointer is.
    if(array[secondPointer] < pivotValue)

    // Swap.
    swapLeftWithRight(array, firstPointer, secondPointer);

    // Move the first pointer forward.
    firstPointer++;



    // When done with this partitioning, swap the pivot back to its original position.
    swapLeftWithRight(array, right, firstPointer);

    return firstPointer;










    share|improve this question























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I am trying to understand how QuickSelect partitioning works, and there are a few things I don't get, I will try to explain how I see it (please notice that I have renamed the variables and made my comments to try to understand it, so maybe some renaming or commenting is wrong):



      • First, the value of the pivot is the value of the index the pivot is at, that makes sense.

      • We now swap the pivot to the end of the Array, why?

      • We have a first pointer which starts at left, because the first pointer should of course start at the start.

      • In the for loop we have a second pointer, which also starts at left, why?. Shouldn't it start at the other end?

      • If where we are at is less than the pivot value, swap them, so we get the lesser elements to the left.

      • At the end swap the pivot back (this leads to my fist "why").

      • At the end we return the first pointer, which I assume is because that is the only element left in the Array?

      I have seen different kinds of implementations, and I have found that most if not all do this.



      // Partitioning.
      private static int quickSelectPartition(int array, int left, int right, int pivotIndex)
      // The value of the pivot depends on the value at the random index that we got.
      int pivotValue = array[pivotIndex];

      // Move the pivot to the end.
      swapLeftWithRight(array, pivotIndex, right);

      // First pointer starts from left.
      int firstPointer = left;

      // Second pointer starts from left.
      for(int secondPointer = left; secondPointer < right; secondPointer++)

      // If the value at the second pointer is less than pivot value, swap it to where the first pointer is.
      if(array[secondPointer] < pivotValue)

      // Swap.
      swapLeftWithRight(array, firstPointer, secondPointer);

      // Move the first pointer forward.
      firstPointer++;



      // When done with this partitioning, swap the pivot back to its original position.
      swapLeftWithRight(array, right, firstPointer);

      return firstPointer;










      share|improve this question













      I am trying to understand how QuickSelect partitioning works, and there are a few things I don't get, I will try to explain how I see it (please notice that I have renamed the variables and made my comments to try to understand it, so maybe some renaming or commenting is wrong):



      • First, the value of the pivot is the value of the index the pivot is at, that makes sense.

      • We now swap the pivot to the end of the Array, why?

      • We have a first pointer which starts at left, because the first pointer should of course start at the start.

      • In the for loop we have a second pointer, which also starts at left, why?. Shouldn't it start at the other end?

      • If where we are at is less than the pivot value, swap them, so we get the lesser elements to the left.

      • At the end swap the pivot back (this leads to my fist "why").

      • At the end we return the first pointer, which I assume is because that is the only element left in the Array?

      I have seen different kinds of implementations, and I have found that most if not all do this.



      // Partitioning.
      private static int quickSelectPartition(int array, int left, int right, int pivotIndex)
      // The value of the pivot depends on the value at the random index that we got.
      int pivotValue = array[pivotIndex];

      // Move the pivot to the end.
      swapLeftWithRight(array, pivotIndex, right);

      // First pointer starts from left.
      int firstPointer = left;

      // Second pointer starts from left.
      for(int secondPointer = left; secondPointer < right; secondPointer++)

      // If the value at the second pointer is less than pivot value, swap it to where the first pointer is.
      if(array[secondPointer] < pivotValue)

      // Swap.
      swapLeftWithRight(array, firstPointer, secondPointer);

      // Move the first pointer forward.
      firstPointer++;



      // When done with this partitioning, swap the pivot back to its original position.
      swapLeftWithRight(array, right, firstPointer);

      return firstPointer;







      java algorithm big-o quicksort quickselect






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 10 at 19:24







      user7722505





























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          It's all about the contracts. The contract for quickSelectPartition, if it existed, would say something like "permutes the array and returns the new index of the pivot; all elements before the pivot are less than the pivot, and all elements after the pivot are greater than or equal to the pivot".



          Swapping the pivot to the end and then back to firstPointer is how this function connects its contract to the loop invariant: "the elements at indexes left..firstPointer-1 are less than the pivot; the elements at indexes firstPointer..secondPointer-1 are greater than or equal to the pivot". When secondPointer is left, this invariant trivially holds; the goal of the loop is to increase secondPointer to right while preserving the invariant. We could keep the pivot in the middle of these arrays, but to answer all of your questions, it's more efficient not to have the pivot be constantly moving to follow secondPointer.



          There are certainly other ways to handle partitioning, so the meta-answer to your whys is that this is the way the code author decided to do it.






          share|improve this answer




















          • I see. So we move the pivot out of the way for simplicity. So essentially it is made up of four parts, left, firstP, secondP, and right. The left itself which is the start of the array. The first pointer which increments away from left, and all values between left and first pointer are less than pivot. We then have second pointer that moves towards right, and all values between first and second pointer are greater than pivot. At the end we move pivot back between the end of the first and second pointers. Is this correct?
            – user7722505
            Nov 10 at 19:47











          • @mth1417 Yes, that's right.
            – David Eisenstat
            Nov 10 at 19:50










          • Thank you I get it now.
            – user7722505
            Nov 10 at 19:51










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53242614%2fquick-select-partitioning%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown
























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote



          accepted










          It's all about the contracts. The contract for quickSelectPartition, if it existed, would say something like "permutes the array and returns the new index of the pivot; all elements before the pivot are less than the pivot, and all elements after the pivot are greater than or equal to the pivot".



          Swapping the pivot to the end and then back to firstPointer is how this function connects its contract to the loop invariant: "the elements at indexes left..firstPointer-1 are less than the pivot; the elements at indexes firstPointer..secondPointer-1 are greater than or equal to the pivot". When secondPointer is left, this invariant trivially holds; the goal of the loop is to increase secondPointer to right while preserving the invariant. We could keep the pivot in the middle of these arrays, but to answer all of your questions, it's more efficient not to have the pivot be constantly moving to follow secondPointer.



          There are certainly other ways to handle partitioning, so the meta-answer to your whys is that this is the way the code author decided to do it.






          share|improve this answer




















          • I see. So we move the pivot out of the way for simplicity. So essentially it is made up of four parts, left, firstP, secondP, and right. The left itself which is the start of the array. The first pointer which increments away from left, and all values between left and first pointer are less than pivot. We then have second pointer that moves towards right, and all values between first and second pointer are greater than pivot. At the end we move pivot back between the end of the first and second pointers. Is this correct?
            – user7722505
            Nov 10 at 19:47











          • @mth1417 Yes, that's right.
            – David Eisenstat
            Nov 10 at 19:50










          • Thank you I get it now.
            – user7722505
            Nov 10 at 19:51














          up vote
          0
          down vote



          accepted










          It's all about the contracts. The contract for quickSelectPartition, if it existed, would say something like "permutes the array and returns the new index of the pivot; all elements before the pivot are less than the pivot, and all elements after the pivot are greater than or equal to the pivot".



          Swapping the pivot to the end and then back to firstPointer is how this function connects its contract to the loop invariant: "the elements at indexes left..firstPointer-1 are less than the pivot; the elements at indexes firstPointer..secondPointer-1 are greater than or equal to the pivot". When secondPointer is left, this invariant trivially holds; the goal of the loop is to increase secondPointer to right while preserving the invariant. We could keep the pivot in the middle of these arrays, but to answer all of your questions, it's more efficient not to have the pivot be constantly moving to follow secondPointer.



          There are certainly other ways to handle partitioning, so the meta-answer to your whys is that this is the way the code author decided to do it.






          share|improve this answer




















          • I see. So we move the pivot out of the way for simplicity. So essentially it is made up of four parts, left, firstP, secondP, and right. The left itself which is the start of the array. The first pointer which increments away from left, and all values between left and first pointer are less than pivot. We then have second pointer that moves towards right, and all values between first and second pointer are greater than pivot. At the end we move pivot back between the end of the first and second pointers. Is this correct?
            – user7722505
            Nov 10 at 19:47











          • @mth1417 Yes, that's right.
            – David Eisenstat
            Nov 10 at 19:50










          • Thank you I get it now.
            – user7722505
            Nov 10 at 19:51












          up vote
          0
          down vote



          accepted







          up vote
          0
          down vote



          accepted






          It's all about the contracts. The contract for quickSelectPartition, if it existed, would say something like "permutes the array and returns the new index of the pivot; all elements before the pivot are less than the pivot, and all elements after the pivot are greater than or equal to the pivot".



          Swapping the pivot to the end and then back to firstPointer is how this function connects its contract to the loop invariant: "the elements at indexes left..firstPointer-1 are less than the pivot; the elements at indexes firstPointer..secondPointer-1 are greater than or equal to the pivot". When secondPointer is left, this invariant trivially holds; the goal of the loop is to increase secondPointer to right while preserving the invariant. We could keep the pivot in the middle of these arrays, but to answer all of your questions, it's more efficient not to have the pivot be constantly moving to follow secondPointer.



          There are certainly other ways to handle partitioning, so the meta-answer to your whys is that this is the way the code author decided to do it.






          share|improve this answer












          It's all about the contracts. The contract for quickSelectPartition, if it existed, would say something like "permutes the array and returns the new index of the pivot; all elements before the pivot are less than the pivot, and all elements after the pivot are greater than or equal to the pivot".



          Swapping the pivot to the end and then back to firstPointer is how this function connects its contract to the loop invariant: "the elements at indexes left..firstPointer-1 are less than the pivot; the elements at indexes firstPointer..secondPointer-1 are greater than or equal to the pivot". When secondPointer is left, this invariant trivially holds; the goal of the loop is to increase secondPointer to right while preserving the invariant. We could keep the pivot in the middle of these arrays, but to answer all of your questions, it's more efficient not to have the pivot be constantly moving to follow secondPointer.



          There are certainly other ways to handle partitioning, so the meta-answer to your whys is that this is the way the code author decided to do it.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 10 at 19:40









          David Eisenstat

          36.5k73372




          36.5k73372











          • I see. So we move the pivot out of the way for simplicity. So essentially it is made up of four parts, left, firstP, secondP, and right. The left itself which is the start of the array. The first pointer which increments away from left, and all values between left and first pointer are less than pivot. We then have second pointer that moves towards right, and all values between first and second pointer are greater than pivot. At the end we move pivot back between the end of the first and second pointers. Is this correct?
            – user7722505
            Nov 10 at 19:47











          • @mth1417 Yes, that's right.
            – David Eisenstat
            Nov 10 at 19:50










          • Thank you I get it now.
            – user7722505
            Nov 10 at 19:51
















          • I see. So we move the pivot out of the way for simplicity. So essentially it is made up of four parts, left, firstP, secondP, and right. The left itself which is the start of the array. The first pointer which increments away from left, and all values between left and first pointer are less than pivot. We then have second pointer that moves towards right, and all values between first and second pointer are greater than pivot. At the end we move pivot back between the end of the first and second pointers. Is this correct?
            – user7722505
            Nov 10 at 19:47











          • @mth1417 Yes, that's right.
            – David Eisenstat
            Nov 10 at 19:50










          • Thank you I get it now.
            – user7722505
            Nov 10 at 19:51















          I see. So we move the pivot out of the way for simplicity. So essentially it is made up of four parts, left, firstP, secondP, and right. The left itself which is the start of the array. The first pointer which increments away from left, and all values between left and first pointer are less than pivot. We then have second pointer that moves towards right, and all values between first and second pointer are greater than pivot. At the end we move pivot back between the end of the first and second pointers. Is this correct?
          – user7722505
          Nov 10 at 19:47





          I see. So we move the pivot out of the way for simplicity. So essentially it is made up of four parts, left, firstP, secondP, and right. The left itself which is the start of the array. The first pointer which increments away from left, and all values between left and first pointer are less than pivot. We then have second pointer that moves towards right, and all values between first and second pointer are greater than pivot. At the end we move pivot back between the end of the first and second pointers. Is this correct?
          – user7722505
          Nov 10 at 19:47













          @mth1417 Yes, that's right.
          – David Eisenstat
          Nov 10 at 19:50




          @mth1417 Yes, that's right.
          – David Eisenstat
          Nov 10 at 19:50












          Thank you I get it now.
          – user7722505
          Nov 10 at 19:51




          Thank you I get it now.
          – user7722505
          Nov 10 at 19:51

















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53242614%2fquick-select-partitioning%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Top Tejano songwriter Luis Silva dead of heart attack at 64

          ReactJS Fetched API data displays live - need Data displayed static

          政党