## Quicksort Iterative

Back to Programming

### Description

Quicksort is a sorting algorithm based on the divide and conquer paradigm. In this algorithm the array is divided into two sub-lists, one sub-list will contain the smaller elements and another sub-list will contain the larger elements and then these sub-lists are sorted again using recursion.

For that these techniques are followed:

1. One element is picked from the list known as the pivot element.

2. The list is then reordered such that the smaller elements of the pivot go to its left sub-list and the greater elements of the pivot element go to its right sublist(the equal element can go either side) and after this reordering, the pivot element will be at its final sorted position.

3. The above two steps are recursively applied to the sublists in a similar way and thus the array gets sorted.

There are various ways to select a pivot element-

1. The first element can be chosen as the pivot element

2. The last element can be chosen as the pivot element

3. Any random element can be chosen as the pivot element

4. The median element can be chosen as the pivot element

Quicksort recursion algorithm is divided into two-part:

1) PARTITION  2) Quicksort_Iterative

``````PARTITION (A, low, high)
{ 	pivot = A[r] 		// x is pivot
i = low – 1
for (j = low to high – 1)
{        if(A[j] <= pivot)
{ 	i = i + 1
exchange A[i] with A[j]
}
}
exchange A[i + 1] with A[r]
return i + 1
}``````

``````QuickSort_Iterative (A,low,high)
{
// Create an auxiliary stack
int stack[ high - low + 1 ];

// initialize top of stack
int top = -1;

// push initial values of low and high to stack
stack[ ++top ] = low;
stack[ ++top ] = high;

// Keep popping from stack while is not empty
while ( top >= 0 )
{
// Pop h and l
high = stack[ top-- ];
low = stack[ top-- ];

/* Here we called partition function which give us the position from where
we partition the list into left and right sublist */
int part = partition( A, low, high );

// push all left elements of pivot to stack
if ( p-1 > low )
{
stack[ ++top ] = low;
stack[ ++top ] = part - 1;
}

// push all right elements of pivot to stack
if ( p+1 < h )
{
stack[ ++top ] = p + 1;
stack[ ++top ] = high;
}
}
} ``````

Illustrating this procedure by example:

Suppose there is an array of  7 elements. And the array of unsorted elements is:

low = 0, high = 6 now as per algorithm i = low -1 = 0 – 1-1 and pivot = x = 4

For we travers the array we continue loop j = low to high -1.

1) So, for first loop  i = -1 and j = 0. Now A[j]x i.e. 5 > 4 so, no swapping required between i and j.

2) Next (2nd) loop i = -1 and j = 1 below:

But here again A[j] > x i.e. 7 > 4 so, no swapping required between i and j.

3) Next (3rd) loop i = -1 and j = 2 (Incremented by 1) bellow:

Here A[j] > x i.e. 6 > 4 so, no swapping required between i and j.

4) Next (4th) loop i = -1 and j = 3 (Incremented by 1) bellow:

Here A[j] < x i.e. 1 < 4 so, we first increment i by 1 i.e. i = + 1 = -1 + 1 = 0 and swap with j.

5) Next (4th) loop i = 0 and j = 4 (Incremented by 1) bellow:

Here A[j] < x i.e. 3 < 4 so, we first increment i by 1 i.e. i = + 1 = 0 + 1 = 1 and swap with j.

6) Next (4th) loop i = 1 and  j = 5 (Incremented by 1) bellow:

Here A[j] < x i.e. 2 < 4 so, we first increment i by 1 i.e. i = + 1 = 1 + 1 = 2 and swap with j.

Now end of loop because j = 5 = high -1. So, increment i by 1 i.e. i = i + 1 = 2 +1 = and swap with Pivot i.e. x.

Now the left-hand side of the pivot contains all smaller elements and the right-hand side of the pivot contains all larger elements.

So, after getting the position from where we partition left sub-list and right sub-list we use stack to compute each list separately by push and pop and continue it until the stack is empty.

Illustration of Iterative quicksort algorithm:

(1)  Initially the entire list (0, 6) is pushed into the stack.

(2) The list (0,6) is POPed and divided into sub-list L1(0,2) and L2(4,6) using PARTITION ALGORITHM and pushed into the stack. Now we do the same PARTITION algorithm for the left and right sub-list.

(3) The right sub-list (4,6) is POPed and divided into two sub-list L1(4,4) and L2(5,6).

L1(4,4) is not required to push because it is a single element, no push operation needed as they are either empty or containing a single element.

(4) The list (5,6) is POPed and divided into sub-list L1(6,6) and L2(empty) using the Divided procedure. No push operation needed as they are either empty or containing a single element.

The list (0,2) is POPed and divided into sub-list L1(0,0) and L2(2,2) using divided procedure. No push operation needed as they are either empty or containing single element.

Now the sorted elements are:

### Code

CHARACTERISTICS:

1. It is totally based on the divide and conquer paradigm.

2. The data can be sorted very fast using this algorithm.

3. It is not a stable sort.

TIME COMPLEXITY ANALYSIS:

The time complexity of recursive and iterative quicksort is the same:  https://mycareerwise.com/programming/category/sorting/quick-sort-using-recursion

SPACE COMPLEXITY:

The space complexity of the in-place quicksort is O(1) as it does not require any extra space for sorting. But for each recursive call, the algorithm needs to use or maintain the stack to store some amount of data

Now, what is space complexity behind it and it depends on what is the depth of stack use. Now the depth of the stack is the height of the tree.

So, if the tree is a balanced tree then we know level of the tree is log n.

So, space complexity O(log n) is the best case.

But worst case tree can look like that

1. It is one of the fastest sorting algorithms.

2. It does not need any additional space for sorting.

3. It works efficiently for a large amount of data.

4. The average case complexity is better than bubble or selection sort. APPLICATIONS:

1. It is used in commercial applications whereas it runs fast, no additional storage space is required.

2. It is not used in such applications where guaranteed response time is required.

Related