Fundamentals of Data Structure and Algorithm (Wang Zhuo) (31): Directly insert sorting code

Direct insertion sorting is implemented into the actual code implementation:

Table of contents

 Project 1:

Note: 

question:

 Project 2:

standard answer

Annotated version:

Uncommented version:

Notes: (explain)

(1):i = 2:

(2):     if (L.r[i].key < L.r[i - 1].key)

(3):            for (j = i - 1; L.r[0].key < L.r[j].key; j--)

(4): L.r[j + 1] = L.r[j];

(5): If the element (j+1) is not backed up at the position (j+2) when inserting, what should I do if the data is lost?

(6): L.r[j + 1] = L.r[0];


 Project 1:

void InsertSort(SqList& L) 
//咱们从第一个开始,一个一个插入
{
    KeyType* i,*j;

    for (int k = 1; k <= L.length; k++)
        //遍历整个序列表(有的有序,有的无序)
    {
        if (L.r[k].key != NULL)
            L.r[0].key = L.r[k].key;
        //给哨兵赋值
        j =& L.r[k].key;

        while (1)
            //结束循环条件是什么?
        {
            if()
        }
    }
}

Note: 

sort:

n. Classification; Sorting; Type; Category; Variety; A certain type (or a certain type) of people;
vt. Arrange; Classify...

question:

The results are written here for what we found:

We can compare sentinels with j

But it cannot be executed with j: move all the elements of j and the ordered sequence after j to the back by one bit

It is not even possible to use j to find the element position before/after j

So, for i and j, we cannot use the (KeyType*)type:

Set i, j as int type


 Project 2: (still wrong, see next section for correction results)

void InsertSort(SqList& L) 
//咱们从第一个开始,一个一个插入
{
    for (int i = 1; i <= L.length; i++)
        //遍历整个序列表(有的有序,有的无序)
        //在每次的循环中,k代表的是无序队列的队头
    {
        if (L.r[i].key != NULL)
            L.r[0].key = L.r[i].key;
        //给哨兵赋值
        int j = i - 1;

        while (j>=0)
            //结束循环条件是什么?
        {
            if (L.r[j].key >= L.r[0].key)
            {
                for (int a = i; a >= j; a--)
                    L.r[a].key = L.r[a - 1].key;
                L.r[j].key = L.r[0].key;
                //已经有k++,没必要i++;
            }
            else if (L.r[j].key < L.r[0].key)
                j--;
        }
    }
}

Then, we went to refer to the standard answer: (watched the video)

standard answer

Annotated version:

void InsertSort(SqList& L)
{
    int i, j;
    for (i = 2; i <= L.length; i++)
        //i表示哨兵后面的第一个元素,同时也代表着每次比较的
        // 有序序列的最后一个元素

        // i 表示的是元素的位置(第几个元素)而不是位序(数组下标)
    {
        // 前面 i 表示的是元素的位置(第几个元素)而不是位序(数组下标)
        if (L.r[i].key < L.r[i - 1].key)
            // 如果第(i+1)个元素小于第(i)个元素(才开始改动)
            //其实当i表示元素的位置(第几个元素),不是数组下标时
            //这样写才是对的,就应该这样写
        {
            L.r[0] = L.r[i];
            //就把第(i+1)个元素复制为哨兵
            for (j = i - 1; 
                //j = i - 1 从:指向每次比较的有序序列最后一个元素 开始
                L.r[0].key < L.r[j].key;
                //比较指向的元素是否大于哨兵元素
                j--)
                // 一直向前比较到最后一个大于哨兵的元素为止(<=就停止)
                L.r[j + 1] = L.r[j];
            //每次比较指向的元素大于哨兵元素,就把
            //有序序列最后一个元素【位序为j】复制到
            //(j+1)【无序序列的第一个元素;==哨兵元素】位置一次

            // 如果插入时(j+1)的元素没有备份在(j+2)的位置,数据丢失怎么办?
            // 不可能,因为根据条件判断的语句:
            // 至少原来的(j+1)的位置是要大于哨兵的,那么根据循环规则的运行:
            // 只要大于哨兵就进行备份复制的操作,所以该情形(况)不可能发生
            L.r[j + 1] = L.r[0];  
            //该语句运行的情况(阶段):
            // 先是让所有大于哨兵的元素都已经被比较完了,比完了以后
            // 下一步操作肯定还是继续往前面(的元素)比,然后条件判断为失败,跳出循环
            // 此时我们的 j 指针指向的:
            // 是我们第一个不满足条件判别式的元素(第一个<=哨兵的元素)
            // 那么/所以,我们就在(j+1)的位置上插入该元素
        }
    }
}

Uncommented version:

void InsertSort(SqList& L)
{
    int i, j;
    for (i = 2; i <= L.length; i++)
    {

        if (L.r[i].key < L.r[i - 1].key)
        {
            L.r[0] = L.r[i];
            for (j = i - 1; L.r[0].key < L.r[j].key; j--)
                L.r[j + 1] = L.r[j]; 
            L.r[j + 1] = L.r[0]; 
        }
    }
}

Notes: (explain)


(1):i = 2:

 i represents the position of the element (the number of elements) rather than the bit order (array subscript)

At the beginning, means the first element after the sentinel

At the same time, the back also represents the first element of the unordered sequence for each comparison

So it should start with the second


(2):     if (L.r[i].key < L.r[i - 1].key)

If the (i+1)th element [the first element of the unordered sequence] is less than the (i)th element [the last element of the ordered sequence]

Just copy the (i+1)th element [the first element of the unordered sequence] as a sentinel


(3):            for (j = i - 1; L.r[0].key < L.r[j].key; j--)

j = i - 1 from: points to the last element of the sorted sequence for each comparison

Compares whether the element pointed to is greater than the sentinel element

 Compare forward until the last element is greater than the sentinel (<= stops)


(4): L.r[j + 1] = L.r[j];

The element pointed to by each comparison is greater than the sentinel element

Just copy the last element of the ordered sequence [the bit order is j] to the position of (j+1) [the first element of the unordered sequence; == sentinel element] once


(5): If the element (j+1) is not backed up at the position (j+2) when inserting, what should I do if the data is lost?

Impossible, because the conditional statement:

At least the original (j+1) position is greater than the sentinel, then run according to the loop rule:

As long as it is larger than the sentinel, the backup copy operation will be performed, so this situation (condition) cannot happen


(6): L.r[j + 1] = L.r[0];

The status (stage) of this statement:
 First, let all the elements larger than the sentinel have been compared. After the comparison, the next
operation must continue to compare to the previous (element), and then the condition is judged as failure, and we jump out of the loop.
At this point we The j pointer points to:
it is our first element that does not satisfy the conditional discriminant (the first element <= sentinel)
then/so, we insert the element at the position of (j+1)


Answer idea:

Compare the sentinel (bit order 0) element with the element pointed to by pointer j

If greater than or equal to: (the sentinel element is greater than or equal to the element pointed to by pointer j)
【Exchange elements】

Move all the elements of the ordered sequence after j and j to the back by one bit

(Because the new element to be inserted has already been placed in the sentinel, we don’t have to worry about whether there will be data loss if we go back one bit)

Insert the sentinel element at the position pointed to by pointer j
 

If less than: (the sentinel element is less than the element pointed to by pointer j)
[Continue to compare, compare with the previous one]

j--;

Guess you like

Origin blog.csdn.net/Zz_zzzzzzz__/article/details/130310132
Recommended