Number Pyramid Algorithm - algorithm

I was searching around the internet trying to find the algorithm of the following pyramid:
1
2 3 2
3 4 5 4 3
4 5 6 7 6 5 4
5 6 7 8 9 8 7 6 5
6 7 8 9 10 11 10 9 8 7 6
7 8 9 10 11 12 13 12 11 10 9 8 7
8 9 10 11 12 13 14 15 14 13 12 11 10 9 8
9 10 11 12 13 14 15 16 17 16 15 14 13 12 11 10 9
10 11 12 13 14 15 16 17 18 19 18 17 16 15 14 13 12 11 10
I wasn't able to find the algorithm, my question is: Does anyone know the algorithm and/or name for this type of pyramid?
Any help is greatly appreciated. I'm sorry if anything in the post is wrong in some way, new posting here.

Here's one solution .... but you should not be lazy, this isn't so hard :)
It is written in Java ....
What you see in the System.out.print() is "Ternary operator". You need to check if it is two digit number, to reduce the number of empty spaces.
public static void Pyramid(int rows) {
int r = 1; // r is current row
int emptySpaces = rows;
while(r <= rows) {
//print the empty spaces (3 empty spaces in one iteration)
for(int i = 1; i < emptySpaces; i++) {
System.out.print(" ");
}
//print the numbers to the middle including the middle number
for(int i = 0; i < r; i++) {
System.out.print((r+i)/10 == 0 ? (r+i + " ") : (r+i + " "));
}
//print the numbers from the middle to the end
for(int i = r-2; i >= 0; i--) {
System.out.print((r+i)/10 == 0 ? (r+i + " ") : (r+i + " "));
}
//print new line, reduce empty spaces
System.out.println("");
emptySpaces--;
r++;
}
}

Related

i tried 2 style of nested loop in golang, but it has different output

i have this quiz, you should make an output like this, and i search youtube tutorials for "for golang" and it explain that it has 2 style of for in golang,
1
21
11
12
13
14
22
11
12
13
14
23
11
12
13
14
24
11
12
13
14
2
21
11
12
13
14
22
11
12
13
14
23
11
12
13
14
24
11
12
13
14
3
21
11
12
13
14
22
11
12
13
14
23
11
12
13
14
24
11
12
13
14
4
21
11
12
13
14
22
11
12
13
14
23
11
12
13
14
24
11
12
13
14
5
21
11
12
13
14
22
11
12
13
14
23
11
12
13
14
24
11
12
13
14
it should be vertically outputted, not horizontally, so i build 3 variable, i = 1, j = 21, and k = 11, and i use for to automatically increase the value, the 1st style worked, but the 2nd style somehow its different
yt vid : https://www.youtube.com/watch?v=jZ-llP_yKNo on 5:28 min he explain that for has 2 style
1st style :
for i:=1; i <= 5; i++{
fmt.Println(i)
for j:=21; j <= 24; j++ {
println(j)
for k:=11; k<=14; k++ {
fmt.Println(k)
}
}
}
2nd style :
i:=1
j:=21
k:=11
for i <= 5{
fmt.Println(i)
i++
for j <= 24 {
println(j)
j++
for k<=14 {
fmt.Println(k)
k++
}
}
}
It's not about the syntax but about your logic.
In the 1st style with for i := ..., whenever next loop run, you reset the value to the init state, means it always sets j to 21 and k to 11. So there will a many sub loop runs.
In contrast, 2nd style, you init value j and k right before going to loop. So in the second loop of i, j and k are still the same value with 25 and 15 in that order.
There are multiple options to print the output in the golang.
fmt.Println appends a new line in the end.
fmt.Printf prints content as it is.
For more details read the documentation.
for i := 1; i <= 5; i++ {
fmt.Printf("%v ", i)
for j := 21; j <= 24; j++ {
fmt.Printf("%v ", j)
for k := 11; k <= 14; k++ {
fmt.Printf("%v ", k)
}
}
}
Output
1 21 11 12 13 14 22 11 12 13 14 23 11 12 13 14 24 11 12 13 14 2 21 11 12 13 14 22 11 12 13 14 23 11 12 13 14 24 11 12 13 14 3 21 11 12 13 14 22 11 12 13 14 23 11 12 13 14 24 11 12 13 14 4 21 11 12 13 14 22 11 12 13 14 23 11 12 13 14 24 11 12 13 14 5 21 11 12 13 14 22 11 12 13 14 23 11 12 13 14 24 11 12 13 14
To add a new line use the \n escape sequence.
Check the running code link

How to make a N×N matrix each of i-th row and i-th column having all the elements 1 to 2N-1?

This question was asked as a puzzle in one Book of Puzzles by RS AGGARWAL, which stated the problem as to build an order N matrix where each i'th row and i'th column combined have all the elements from 1 to 2N-1.
For instance, for N=2
[3,2]
[1,3]
I want to know when is an answer possible for it for which values of N it is possible to make a matrix and how to make it? and write code for it
this has simple solution for square matrices where n is power of 2 so n=1,2,4,8,16,... do not ask me why there surely is some math proof for it ...
The algorithm to create such matrix is easy:
clear matrix (with 0)
loop i through all values i=1,2,3...2n-1
for each i find all locations where i matrix is not yet filled (0) and there is not i present in row and column
fill the position with i and repeat until no such location found.
In C++ something like this:
//---------------------------------------------------------------------------
const int n=8;
int m[n][n];
//---------------------------------------------------------------------------
// compute histogram u[n+n] of values per ith row,col of m[n][n]
void hist_rst(int *u ) { for (int j=0;j<n+n;j++) u[j]=0; }
void hist_row(int *u,int m[n][n],int i) { for (int j=0;j<n;j++) u[m[j][i]]=1; }
void hist_col(int *u,int m[n][n],int i) { for (int j=0;j<n;j++) u[m[i][j]]=1; }
//---------------------------------------------------------------------------
void matrix_init(int m[n][n])
{
int i,x,y,h[n][n+n];
// clear matrix (unused cells)
for (x=0;x<n;x++)
for (y=0;y<n;y++)
m[x][y]=0;
// clear histograms
for (i=0;i<n;i++) hist_rst(h[i]);
// try to fill values 1..2n-1
for (i=1;i<n+n;i++)
{
// find free position
for (x=0;x<n;x++) if (!h[x][i])
for (y=0;y<n;y++) if (!h[y][i])
if (!m[x][y])
{
// set cell
m[x][y]=i;
h[x][i]=1;
h[y][i]=1;
break;
}
}
}
//---------------------------------------------------------------------------
here few outputs:
1
1 3
2 1
1 5 6 7
2 1 7 6
3 4 1 5
4 3 2 1
1 9 10 11 12 13 14 15
2 1 11 10 13 12 15 14
3 4 1 9 14 15 12 13
4 3 2 1 15 14 13 12
5 6 7 8 1 9 10 11
6 5 8 7 2 1 11 10
7 8 5 6 3 4 1 9
8 7 6 5 4 3 2 1
for non power of 2 matrices you could use backtracking but take in mind even 4x4 matrix will have many iterations to check ... so some heuristics would need to be in place to make it possible in finite time... as brute force is (n+n)^(n*n) so for n=4 there are 281474976710656 combinations to check ...
[edit1] genere&test solution for even n
//---------------------------------------------------------------------------
const int n=6;
int m[n][n];
//---------------------------------------------------------------------------
// compute histogram u[n+n] of values per ith row,col of m[n][n]
void hist_rst(int *u ) { for (int j=0;j<n+n;j++) u[j]=0; }
void hist_row(int *u,int m[n][n],int i) { for (int j=0;j<n;j++) u[m[j][i]]=1; }
void hist_col(int *u,int m[n][n],int i) { for (int j=0;j<n;j++) u[m[i][j]]=1; }
//---------------------------------------------------------------------------
void matrix_init2(int m[n][n]) // brute force
{
int x,y,a,ax[(n*n)>>1],ay[(n*n)>>1],an,u[n+n];
// clear matrix (unused cells)
for (x=0;x<n;x++)
for (y=0;y<n;y++)
m[x][y]=0;
// main diagonal 1,1,1,1...
for (x=0;x<n;x++) m[x][x]=1;
// 1st row 1,2,3...n
for (x=1;x<n;x++) m[x][0]=x+1;
// cells for brute force
for (an=0,x=0;x<n;x++)
for (y=0;y<x;y++)
if (!m[x][y])
{
ax[an]=x;
ay[an]=y;
an++;
m[x][y]=2;
}
// brute force attack values 2,3,4,5,...,n-1
for (;;)
{
// increment solution
for (a=0;a<an;a++)
{
x=ax[a];
y=ay[a];
m[x][y]++;
if (m[x][y]<=n) break;
m[x][y]=2;
}
if (a>=an) break; // no solution
// test
for (x=0;x<n;x++)
{
hist_rst(u);
hist_col(u,m,x);
hist_row(u,m,x);
for (y=1;y<=n;y++) if (!u[y]) { y=0; x=n; break; }
}
if (y) break; // solution found
}
// mirror other triangle
for (x=0;x<n;x++)
for (y=0;y<x;y++)
m[y][x]=m[x][y]+n-1;
}
//---------------------------------------------------------------------------
however its slow so do not try to go with n>6 without more optimizations/better heuristics... for now it is using triangle+mirror and diagonal + first row hard-coded heuristics.
maybe somehow exploit the fact that each iterated value will be placed n/2 times could speed this up more but too lazy to implement it ...
Here output for n=6:
[ 52.609 ms]
1 2 3 4 5 6
7 1 6 5 3 4
8 11 1 2 4 5
9 10 7 1 6 3
10 8 9 11 1 2
11 9 10 8 7 1
iterating through 5^10 cases ...
As requested by Spektre, here is the 6x6 matrix.
I an interesting property that may be used as heuristic. We need only to solve a triangular matrix because the other half can be easily deduced. We fill the upper (or lower) half of the matrix by values from 1 to n only. We can then complete the matrix by using the property that a[j][i] = 2n + 1 - a[i][j].
Another property I found is that there is a trivial way to place 1, 2 and N in the matrix. The values 1 are all on the diagonal, the values 2 and N are next to the diagonal at a step 2.
Finally, another thing I found is that matrix with odd N have no solutions. It is because the value in a[i][j] belongs to row and column i and row and column j. We thus need an even number of row and columns to store all values.
Here is the 6x6 matrix I found manually.
1 2 3 4 5 6
11 1 6 5 3 4
10 7 1 2 4 5
9 8 11 1 6 3
8 10 9 7 1 2
7 9 8 10 11 1
As we can see 2 + 11 = 6 + 7 = 3 + 10 = 13 = 2*6+1.
Here is a 4x4 matrix
1 2 3 4
7 1 4 3
6 5 1 2
5 6 7 1
Here again 2 + 7 = 4 + 5 = 3 + 6 = 9 = 2*4+1
It is possible to have other permutations of values >N, but with the 2N+1 property we can trivially deduce one triangular matrix from the other.
EDIT
Here is a solution for power two sized matrix. The matrix of size 2048x2048 is generated in 57ms (without printing).
#include <stdio.h>
int **newMatrix(int n) {
int **m = calloc(n, sizeof(int*));
m[0] = calloc(n*n, sizeof(int));
for (int i = 1; i < n; i++)
m[i] = m[0]+i*n;
return m;
}
void printMatrix(int **m, int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
printf("%3d ", m[i][j]);
printf("\n");
}
}
void fillPowerTwoMatrix(int **m, int n) {
// return if n is not power two
if (n < 0 || n&(n-1) != 0)
return;
for (int i = 0; i < n; i++)
m[0][i] = i+1;
for (int w = 1; w < n; w *= 2)
for (int k = 0; k < n; k += 2*w)
for (int i = 0; i < w; i++)
for (int j = k; j < k+w; j++) {
m[i+w][j] = m[i][j+w];
m[i+w][j+w] = m[i][j];
}
int k = 2*n+1;
for (int i = 1; i < n; i++)
for (int j = 0; j < i; j++)
m[i][j] = k - m[j][i];
}
int main() {
int n = 16;
int **m = newMatrix(n);
fillPowerTwoMatrix(m, n);
printMatrix(m, n);
return 0;
}
Here is the matrix 16x16. As can be seen there is a symmetry that is exploited to efficiently generate the matrix.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
31 1 4 3 6 5 8 7 10 9 12 11 14 13 16 15
30 29 1 2 7 8 5 6 11 12 9 10 15 16 13 14
29 30 31 1 8 7 6 5 12 11 10 9 16 15 14 13
28 27 26 25 1 2 3 4 13 14 15 16 9 10 11 12
27 28 25 26 31 1 4 3 14 13 16 15 10 9 12 11
26 25 28 27 30 29 1 2 15 16 13 14 11 12 9 10
25 26 27 28 29 30 31 1 16 15 14 13 12 11 10 9
24 23 22 21 20 19 18 17 1 2 3 4 5 6 7 8
23 24 21 22 19 20 17 18 31 1 4 3 6 5 8 7
22 21 24 23 18 17 20 19 30 29 1 2 7 8 5 6
21 22 23 24 17 18 19 20 29 30 31 1 8 7 6 5
20 19 18 17 24 23 22 21 28 27 26 25 1 2 3 4
19 20 17 18 23 24 21 22 27 28 25 26 31 1 4 3
18 17 20 19 22 21 24 23 26 25 28 27 30 29 1 2
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 1

Observing invalid value inside the loop

I've stumbled on a buggy Golang code that was trying to use mutex to prevent changes to the variables printed in a goroutine:
runtime.GOMAXPROCS(1)
mutex := new(sync.Mutex)
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
mutex.Lock()
go func() {
fmt.Println(i, j, i + j);
mutex.Unlock()
}()
}
}
It is clear to me that mutex doesn't lock directly, but on the next iteration, when the value has been incremented already. What is not clear is why j variable reaches 10 according to the output:
...
0 7 7
0 8 8
0 9 9
1 10 11 <--- isn't supposed to be here
...
1 9 10
2 10 12
...
I tried to debug the code and j = 10 is printed when the outer loop for i increments its value. It looks as if the outer loop was releasing the thread allowing goroutine to execute and see invalid value of 10. Could someone clarify this behavior?
You have data races. The results are undefined.
$ go run -race racer.go
==================
WARNING: DATA RACE
Read at 0x00c000016110 by goroutine 7:
main.main.func1()
/home/peter/gopath/racer.go:17 +0x7f
Previous write at 0x00c000016110 by main goroutine:
main.main()
/home/peter/gopath/racer.go:14 +0xf1
Goroutine 7 (running) created at:
main.main()
/home/peter/gopath/racer.go:16 +0xcd
==================
0 1 1
0 2 2
0 3 3
0 4 4
0 5 5
0 6 6
0 7 7
0 8 8
0 9 9
==================
WARNING: DATA RACE
Read at 0x00c000016108 by goroutine 16:
main.main.func1()
/home/peter/gopath/racer.go:17 +0x50
Previous write at 0x00c000016108 by main goroutine:
main.main()
/home/peter/gopath/racer.go:13 +0x140
Goroutine 16 (running) created at:
main.main()
/home/peter/gopath/racer.go:16 +0xcd
==================
1 10 11
1 1 2
1 2 3
1 3 4
1 4 5
1 5 6
1 6 7
1 7 8
1 8 9
1 9 10
2 10 12
2 1 3
2 2 4
2 3 5
2 4 6
2 5 7
2 6 8
2 7 9
2 8 10
2 9 11
3 10 13
3 1 4
3 2 5
3 3 6
3 4 7
3 5 8
3 6 9
3 7 10
3 8 11
3 9 12
4 10 14
4 1 5
4 2 6
4 3 7
4 4 8
4 5 9
4 6 10
4 7 11
4 8 12
4 9 13
5 10 15
5 1 6
5 2 7
5 3 8
5 4 9
5 5 10
5 6 11
5 7 12
5 8 13
5 9 14
6 10 16
6 1 7
6 2 8
6 3 9
6 4 10
6 5 11
6 6 12
6 7 13
6 8 14
6 9 15
7 10 17
7 1 8
7 2 9
7 3 10
7 4 11
7 5 12
7 6 13
7 7 14
7 8 15
7 9 16
8 10 18
8 1 9
8 2 10
8 3 11
8 4 12
8 5 13
8 6 14
8 7 15
8 8 16
8 9 17
9 10 19
9 1 10
9 2 11
9 3 12
9 4 13
9 5 14
9 6 15
9 7 16
9 8 17
9 9 18
Found 2 data race(s)
exit status 66
$
racer.go:
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
runtime.GOMAXPROCS(1)
mutex := new(sync.Mutex)
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
mutex.Lock()
go func() {
fmt.Println(i, j, i+j)
mutex.Unlock()
}()
}
}
}
Go: Data Race Detector
You have data race, so the results are undefined. Run it with the -race option to see.
When you call mutex.Lock() inside the loop body first, that doesn't block. Then you launch a goroutine that reads i and j and the main goroutine continues to the next iteration of the inner loop, and increments j. Then calls lock again, which will block until the previous goroutine finishes.
But you already have an unsynchronized access (read and write) to j.
Let me to answer why you can get the impossible 10 when print j.
Because when you use goroutine in a loop, fmt.Println(i, j, i+j) race with i++/j++, you cannot determine what value exactly when you print out, and if j increase to the bound, it's possible to print out 10.
if you want to prevent from this race, you can transfer i, j as argument values, e.g.
runtime.GOMAXPROCS(1)
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
go func(a, b, c int) {
fmt.Println(a, b, c);
}(i, j, i+j)
}
}
Hope this helps.

How to pick only 4 set of integers from a set in polynomial time algorithm

The whole thing about this polynomial time is confusing to me for example: I want to write a program in a polynomial time algorithm that will just pick only 4 integers that sum to 0 from a set.
For instance: Let assume I have the following set of integers {8, 20, 3, -2, 3, 7, 16, -9}. How can I pick only 4 distinct integers that sum to 0 from a set in polynomial time without having needed to check through every possible length other than 4? Note in the program I don’t need to search through any other possible length than 4. My expected solution is {8, 3, -2, -9} = 0. knowing fully well that i only need 4 integers from the set {8, 20, 3, -2, 3, 7, 16, -9}.
Edit: Will I found a polynomial time solution of {8, 3, -2, -9} even if I increase only the length of the original set from 8 to 100 integers while I will still have to pick my 4 elements that sum to 0 but from the set of 100 integers will it still be polynomial fast with respect to the size of the input (i.e the number of bits used to store the input)?
The following algorithm runs in O(N^3 * logN).
#include <algorithm>
#include <iostream>
#include <tuple>
#include <vector>
using quadruple = std::tuple<int, int, int, int>;
std::vector<quadruple> find(std::vector<int> vec) {
std::sort(vec.begin(), vec.end());
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
std::vector<quadruple> ret;
for (auto i = 0u; i + 3 < vec.size(); ++i) {
for (auto j = i + 1; j + 2 < vec.size(); ++j) {
for (auto k = j + 1; k + 1 < vec.size(); ++k) {
auto target = 0 - vec[i] - vec[j] - vec[k];
auto it = std::lower_bound(vec.begin() + k + 1,
vec.end(),
target);
if (it != vec.end() && *it == target) {
ret.push_back(std::make_tuple(
vec[i], vec[j], vec[k], target));
}
}
}
}
return ret;
}
int main() {
std::vector<int> input = {8, 20, 3, -2, 3, 7, 16, -9};
auto output = find(input);
for (auto& quad : output) {
std::cout << std::get<0>(quad) << ' '
<< std::get<1>(quad) << ' '
<< std::get<2>(quad) << ' '
<< std::get<3>(quad) << std::endl;
}
}
Try all quadruples without repetitions. This takes at most (N^4-6N³+11N²-6N)/24 attempts each made in constant time.
8 + 20 + 3 - 2 = 29
8 + 20 + 3 + 3 = 34
8 + 20 + 3 + 7 = 38
8 + 20 + 3 + 16 = 47
8 + 20 + 3 - 9 = 22
8 + 20 - 2 + 3 = 29
8 + 20 - 2 + 7 = 33
8 + 20 - 2 + 16 = 42
8 + 20 - 2 - 9 = 17
8 + 20 + 3 + 7 = 38
8 + 20 + 3 + 16 = 47
8 + 20 + 3 - 9 = 22
8 + 20 + 7 + 16 = 51
8 + 20 + 7 - 9 = 26
8 + 20 + 16 - 9 = 35
8 + 3 - 2 + 3 = 12
8 + 3 - 2 + 7 = 16
8 + 3 - 2 + 16 = 25
8 + 3 - 2 - 9 = 0 <==
8 + 3 + 3 + 7 = 21
8 + 3 + 3 + 16 = 30
8 + 3 + 3 - 9 = 5
8 + 3 + 7 + 16 = 34
8 + 3 + 7 - 9 = 9
8 + 3 + 16 - 9 = 18
8 - 2 + 3 + 7 = 16
8 - 2 + 3 + 16 = 25
8 - 2 + 3 - 9 = 0 <==
8 - 2 + 7 + 16 = 29
8 - 2 + 7 - 9 = 4
8 - 2 + 16 - 9 = 13
8 + 3 + 7 + 16 = 34
8 + 3 + 7 - 9 = 9
8 + 3 + 16 - 9 = 18
8 + 7 + 16 - 9 = 22
20 + 3 - 2 + 3 = 24
20 + 3 - 2 + 7 = 28
20 + 3 - 2 + 16 = 37
20 + 3 - 2 - 9 = 12
20 + 3 + 3 + 7 = 33
20 + 3 + 3 + 16 = 42
20 + 3 + 3 - 9 = 17
20 + 3 + 7 + 16 = 46
20 + 3 + 7 - 9 = 21
20 + 3 + 16 - 9 = 30
20 - 2 + 3 + 7 = 28
20 - 2 + 3 + 16 = 37
20 - 2 + 3 - 9 = 12
20 - 2 + 7 + 16 = 41
20 - 2 + 7 - 9 = 16
20 - 2 + 16 - 9 = 25
20 + 3 + 7 + 16 = 46
20 + 3 + 7 - 9 = 21
20 + 3 + 16 - 9 = 30
20 + 7 + 16 - 9 = 34
3 - 2 + 3 + 7 = 11
3 - 2 + 3 + 16 = 20
3 - 2 + 3 - 9 = -5
3 - 2 + 7 + 16 = 24
3 - 2 + 7 - 9 = -1
3 - 2 + 16 - 9 = 8
3 + 3 + 7 + 16 = 29
3 + 3 + 7 - 9 = 4
3 + 3 + 16 - 9 = 13
3 + 7 + 16 - 9 = 17
- 2 + 3 + 7 + 16 = 24
- 2 + 3 + 7 - 9 = -1
- 2 + 3 + 16 - 9 = 8
- 2 + 7 + 16 - 9 = 12
3 + 7 + 16 - 9 = 17
Update:
At the request of the OP, stopped when a solution is found.
8 + 20 + 3 - 2 = 29
8 + 20 + 3 + 3 = 34
8 + 20 + 3 + 7 = 38
8 + 20 + 3 + 16 = 47
8 + 20 + 3 - 9 = 22
8 + 20 - 2 + 3 = 29
8 + 20 - 2 + 7 = 33
8 + 20 - 2 + 16 = 42
8 + 20 - 2 - 9 = 17
8 + 20 + 3 + 7 = 38
8 + 20 + 3 + 16 = 47
8 + 20 + 3 - 9 = 22
8 + 20 + 7 + 16 = 51
8 + 20 + 7 - 9 = 26
8 + 20 + 16 - 9 = 35
8 + 3 - 2 + 3 = 12
8 + 3 - 2 + 7 = 16
8 + 3 - 2 + 16 = 25
8 + 3 - 2 - 9 = 0 <==

How does recursion of Quick sort work?

The functions below are an implementation of Quick sort. Here we take the last element as a pivot.
I understood the partition function(where the pivot comes to its sorted position) but I can't understand the recursive function qs. The function qs calls itself recursively to solve the left side by qs(a,start,pi-1) and the right of the partition by qs(a,pi+1,end).
Does it the solve the left and then the (left of the left) then (the left of(the left of the left), etc, and then left, left...right, etc. Or does it alternate by solving the left side and then right side.
PS: I want to know whats happening inside the computer, the mechanism of this recursion of quick sort. The program is working but I want to know how it works.
int partition(int *a, int start, int end)
{
int pivot=a[end];
int pi=start;
for(int i=start; i<end; i++)
{
if(a[i]<=pivot)
{
swap(a[i],a[pi]);
pi++;
}
}
swap(a[pi], a[end]);
return pi;
}
void qs(int*a, int start, int end)
{
if(start<end)
{
int pi=partition(a,start,end);
qs(a,start,pi-1);
qs(a,pi+1,end);
}
}
Example of the order of operations for Lomuto partition scheme, where pivot = array[high].
quicksort(array, low, pivot-1), quicksort(array, pivot+1, high).
A vertical bar used to show left sub-array, pivot, right sub-array.
11 13 14 12 10 8 9 5 6 4 2 0 1 3 7
5 6 4 2 0 1 3 11 13 14 12 10 8 9 7
5 6 4 2 0 1 3| 7|13 14 12 10 8 9 11
2 0 1 5 6 4 3
2 0 1| 3| 6 4 5
0 2 1
0| 1| 2
4 6 5
4| 5| 6
10 8 9 13 14 12 11
10 8 9|11|14 12 13
8 10 9
8| 9|10
12 14 13
12|13|14
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
The best way for understanding the order in which things are happening that I can suggest you, is by printing some debugging info in your qs method. To achieve that, I would add an additional argument by ref, in which I would count the number of times the qs function is called, and print that info next to the bounds of the partition being solved. e.g.
void qs(int*a, int start, int end, int &stepCount)
{
if(start<end)
{
int currentStep = stepCount++;
cout << "Solving step " << currentStep << " partition from " << start << " to " << end << endl;
int pi=partition(a,start,end);
qs(a,start,pi-1,stepCount);
qs(a,pi+1,end,stepCount);
cout << "Finished solving step " << currentStep << endl;
}
}
Don't understand your PS question. It's very broad. You mean specifically in the partitioning? In how recursion is handled? How the bits move around in memory?

Resources