My understanding of sorting algorithms

The sorting algorithm has always been a problem that puzzles me. As early as when I first came into contact with the data structure, this place puzzled me a lot. It's that feeling of always feeling that something is missing. At the beginning, start over again, study this part seriously, and always remember the concepts as you learn. After a while, let me write these algorithms again, and I can't do it again.

I understand my problem, I just feel that I understand, but in fact, I still don't understand. As long as the logic is messed up once, it's basically oh my gad.

Then I watched the video to find some more easy-to-understand understanding of some algorithms. Still feel something is wrong.

However, in the end, I found some ways of understanding.

Do algorithmic questions about sorting:

First you need to understand how it is sorted. Take selection sort as an example:

 Ok, we know that selection sorting is to find a minimum value in each round.

Continue: Looking at the process of selection and sorting, there were 6 rounds in total, and how many comparisons were made in each round?

This problem is a nested loop problem:

Write the nesting of this loop to proceed to the next step: the formula is that the outer loop represents the row, and the inner loop represents the column. I have read a lot of other explanations, and I personally feel that it is enough to remember this feature for all nested loops.

Back to this algorithm:

  //很明显,外层循环有6轮,那么外层循环的判定就是arr.length-1。这个很简单。
  //表示的范围就是【0~6】
for(int i=0;i<arr.length-1;i++){
   //内层循环表示列。
   for(){
   }
}

Here comes the key point, how to write the inner loop problem! ! !

You must learn well here, because different sorting algorithms basically have different inner loops. But they all have certain rules and commonalities.

We are looking at this algorithm.

Each round is to find the minimum value. In the first round, we searched for 7 elements; in the second round, we searched for 6 elements; in the third round, we searched for 5 elements.

Then the inner loop represents the column: it is equivalent to 7 columns (7 elements) in the first round and 6 columns in the second round (except the first element.)

for(int i=0;i<arr.length-1;i++){
   //内层循环表示列。
   //它的范围就是:0~6(7列)、1~6(除了第一个元素0之外的6列)、2~6(5列)
   for(int j=i;j<arr.length-1;j++){

     }
}

Then, we have solved the problem of loop nesting. Basically, the selection sorting algorithm has solved half of our problem!

Let's look at the commonality of nested loops between different sorting algorithms : take the nested loop of insertion sort as an example.

You can try it yourself by writing this nested statement for the loop:

//6行,就是外循环6次
for(int i=0;i<arr.length-1;i++){
  //内循环,观察这个算法的要求。
  //第一行:从第二列开始和前一个比较。
  //第二行:从第三列和前面两个比较。
  //第三行:就是第四个,和前面三个比较。这里不太好画图,自己画一下图,就是一种滑坡的形状。
  //那么初始条件,我们可以设为i+1。(从第二列开始)。那么判定条件是什么呢?
  //第一次判定只比较一次,第二次判定比较两次,第三次就是比较三次。那就是j>0咯。
  //它的范围就是:1(和0比较)、2~1(和0,1比较)、3~1(和0,1,2比较)
   for(int j=i+1;j>0;j++){

   }
}

 What is the commonality between this algorithm and the nested loop of the selection sort algorithm?

Focus on inner loops.

My understanding is:

   On the premise that the outer loop i represents the number of rows and the inner loop j represents the column. Then i must be used in the initial condition or judgment condition of the inner loop, and it can only be used once. Either i is used in the initial condition or in the decision condition.

比如:看选择排序的算法:
内循环:for(int j=i;j<arr.length-1;j++)
i用在初始条件。

插入排序的算法:
内循环:for(int j=i+1;j>0;j--)
i用在初始条件。

冒泡排序:这个很简单,就是从第一个往后面比较,小的往前,大的往后。
内循环:for(int j=0;j<arr.length-i-i;j++)
i用在判定条件。

上面三个算法的外循环都是一样的。

When I did this algorithm problem before, I wrote it like this:

错误的写法,选择排序:
for(int j=i;j<arr.length-i;j++)

如果是这样写,那么它的范围就是:
0~6(第一轮比较和之前是一样的比较的比较7次)
1~5(这里只比较了5次)
2~4
3~3(到这里就结束了,不会运行。)
造成的问题就是:只有效比较了三行(也不是很有效,只有效比较了第一行)。后面三行就根本不会比较,只打印出来。
而我们需要比较是6行。和i的关系是紧密联系的!
故此:我得出结论,在排序算法或者嵌套循环有关,在内循环里面如果要使用i。那么只能使用一次。

Therefore: I concluded that it is related to sorting algorithms or nested loops, if i is to be used in the inner loop. Then it can only be used once.
 

Ok, this is the end of the question about loop nesting. If you want to train yourself, you can try to print the 9*9 multiplication table, or print the shape of a triangle. These all use nested loops.

Let's look at the algorithm problem:

Take the insertion sort algorithm as an example:

Its core is to compare forwards from the second element. You have to think from the perspective of memory space. The heap and stack are not involved here, and the heap and stack are also very important, but the space changes of the heap and stack will only be learned when object-oriented.

Its space changes: only the first four numbers are taken as an example.

Original data: 56, 34, 45, 12, 67, 52, 4
Changes from the perspective of algorithm assignment:
pairwise comparison, the smaller one is ranked first. From the perspective of the algorithm, the two exchanged positions. Specific changes: 56, 34
, 45, 12 First row: 34 34 45 12 ~ temp=56
               34 
 56 45 12 Second row: 34 45 45 12 ~ temp=56
                34 45 56 12 
 Third row: 34 45 12 12 ~temp=56
                34 45 12 56 
                34 12 12 56 temp=45 
                34 12 45 56 
                12 12 45 56 temp=34
                12 34 45 56 

Our final comparison on the third row is 12, 34, 45, 56, 67, 52, 4.

Then the algorithm can be written:

//外循环6行
for(int i=0;i<arr.length-1;i++){
  //内循环
   for(int j=i+1;j>0;j++){
       if(arr[j] < arr[j-1]){   //看上面的规律,是不是两两比较。然后小的排前面。
          temp = arr[j];
          arr[j-1] = arr[j];
          arr[i] = temp;
      }
   }
  Systemo.out.println(Arrays.toString(arr));  //打印每一行的结果
}

Where is the main problem of the algorithm, mainly the judgment of j, j+1 or j-1. I don't know how to use it, will it cause any trouble. This is the second troublesome problem.

This problem is solved, and basically the algorithmic sorting is easier to understand.

In fact, the usage of j and j+1 is similar to nested loops. That is, the range of j+1 cannot exceed the length of the original array. j-1 cannot be less than the length of the original array. If it is exceeded, basically the algorithm is wrong.

Suggestion: Make a draft, like the example above, to draw the changes in memory. You can't go wrong.

Here, the algorithm about insertion sorting is very interesting. Its core algorithm finds the smallest value from each round. This smallest value cannot be exchanged by pairwise comparison. (Disclosure: Return the index value by comparison. Until you find the index of the smallest value, and then exchange it with the first number.)

Selection sort core algorithm:

for(int i=0;i<arr.length-1;i++){
   //内层循环表示列。
   //它的范围就是:0~6(7列)、1~6(除了第一个元素0之外的6列)、2~6(5列)
   index=i;
   for(int j=i;j<arr.length-1;j++){
        if(arr[index] > arr[j+1]){
           index=j+1;       
       }
     }
       temp = arr[index];   //将第一个位置和找到索引最小的元素进行交换
       arr[i] = arr[index];
       arr[index] = temp;
       System.out.println(Arrays.toString(arr));
}

Choose the sorting algorithm to draw its memory changes.

After that, I will keep adding other algorithms to verify my understanding and conjecture. Written here for the time being.

Supplement: There is another condition for nested loops. In the case of an array used in the loop, the scope of the inner loop cannot exceed the outer loop, and the scope of the outer loop cannot exceed the original array.

Guess you like

Origin blog.csdn.net/qq_55928086/article/details/132011547