Data Structure and Algorithm Fundamentals (Wang Zhuo) (28) Linear Table Search (2): Sequential Search (Binary Search, Block Search)

Table of contents

2. Binary search (binary or bisected search)

Project 1:

The corrected result is as follows:

Project 2:

Question (1): [ST.R[mid].key]

Question (2): equal to: (==) not (=)

Question (3): About division, division by, and integer division

1. About the difference between division and division:

Second, on the problem of divisibility:

Question (4): What should we do when low is equal to high?

So for this situation, it is more appropriate for us to put him in the while loop

Project 3: (final result)

The standard answer version written on the PPT (it does have merits)

Supplement on PPT: recursive implementation version

Three, block search


2. Binary search (binary or bisected search)

The preconditions are the same as before

The program framework written based on the PPT example (example) at the beginning:

At the beginning:

low : the first

high : the last digit

mid : right in the middle

Find numbers less than mid:

Move high to the front of mid (-1)

Then take the new mid = new [right in the middle]

Find numbers greater than mid:

Move low to one bit behind mid (+ 1)

Then take the new mid = new [right in the middle]

However, here, what I wrote is only some core rules of the framework, and I have not sorted out the logical flow of how the program actually works.

So what is written is different from what is written in the standard answer:

Project 1:

int Seaarch_Bin(SSTable ST, KeyType key)
//binary:二进制的; 仅基于两个数字的; 二元的; 由两部分组成的;
{
    int low = 1, high = ST.length, mid = (low + high) / 2;
    while (key != mid)
    {
        if (key < mid)
        {
            high = mid - 1;
            mid = (low + high) / 2;
        }
        else if (key < mid)
            //else
        {
            low = mid + 1;
            mid = (low + high) / 2;
        }
    }
    if (low > high)
        return false;
    else
        return mid;
}

In addition to sorting out the logic, there are many other problems, of course:

Before writing the program, it is better to sort out the logical flow of how the program runs. This is for sure.

There are still many problems in the above version:

  • When comparing the key, you should not write [mid] and change it to [ST.R[mid].key] (we will make a detailed analysis and explanation of this in Project 2)
  • No matter in which case (branch) in the while loop, (all) always execute the [mid = (low + high) / 2;] statement, you should (can) consider merging the statement outside the [if] statement

The corrected result is as follows:

(I think after modifying it to the following result, the result is not wrong, but I am not so sure that it must be right)

int Seaarch_Bin(SSTable ST, KeyType key)
//binary:二进制的; 仅基于两个数字的; 二元的; 由两部分组成的;
{
    int low = 1, high = ST.length, mid = (low + high) / 2;
    while (key != ST.R[mid].key)
    {
        if (key < ST.R[mid].key)
            high = mid - 1;
        else if (key < ST.R[mid].key)//else
            low = mid + 1;
        mid = (low + high) / 2;
    }
    if (low > high)
        return false;
    else
        return mid;
}

In addition, the first thing we need to do is to sort out the logical flow of how the program works.

Convert the program into a logical form similar to that on the PPT: (but this does not mean that what I wrote is wrong)

Project 2:

int Seaarch_Bin(SSTable ST, KeyType key)
//binary:二进制的; 仅基于两个数字的; 二元的; 由两部分组成的;
{
    //不是从R开始吗???
    int low = 1, high = ST.length, mid = (low + high) / 2;
    while (low<=high)
        //一开始我们是想写(key != mid)的判断语句的,但是如果这样写的话我们最后就无法判断他有没有找到
    {
        if (key = mid)
            return mid;
        else if (key < mid)
        {
            high = mid - 1;
            mid= (low + high) / 2;
        }
        else if (key > mid)
            //else
        {
            low = mid + 1;
            mid = (low + high) / 2;
        }
    }
    return 0;
}

Question (1): [ST.R[mid].key]

When comparing the key, you should not write [mid] and change it to [ST.R[mid].key]

(There is also a similar problem in Project 1)

Specific explanation:


First, we need to realize that:

The object to be compared with our key is the specific value in a specific bit sequence (a certain cell) inside the sequence table ST (array)

 At this time, when we look at the structure of the sequence table, we will realize:

In fact, the actual sequence table ST is different from the program we originally took for granted.

typedef int KeyType;

// Data element type definition

struct ElemType

{

    KeyType key;  // key field

    //... // other domains

};

struct SSTable

    //Sequential Search Table

{

    ElemType * R;  // table base address

    int length;   // table length

}; 

SSTable ST;  // Define the sequence table ST

In fact, the effect of the program we wrote earlier is:

Let [key] compare with [the bit number of the element pointed to by the pointer]

And what we actually need to achieve is:

Let [key] compare with [the element data pointed to by the pointer]

And this KeyType element data (keyword data) is in:

In the key field key of the table base address R (although I don’t know what the table base address is )

Plus the datatype:

In the [( KeyType ) type] key field key of the [ ( ElemType * ) type ] table base address R

Therefore, mid should be changed to: ST.R[mid].key


And such an explanation actually solves the problem when we write programs:

Doesn't the array address order start from R? ? ?

The problem


Question (2): equal to: (==) not (=)


Question (3): About division, division by, and integer division

1. About the difference between division and division:

6 divided by 2: divided by

6÷2=3

6 divided by 2: divide

2÷6=⅓

2 divided by 6: divide

6÷2=3

2 divided by 6: divided by

2÷6=⅓

Second, on the problem of divisibility:

Rounding for divisibility:

Take the whole number, round off the decimal

Note: not rounded

In computers, there is only one operator symbol for division, which is "/".

And about whether it is divisible:

Whether it means the rounding result of integer division [note: not rounded] or the final operation result with decimals depends on the divisor and the dividend. More precisely, it is the amount of calculations during the division process

If all operands [all divisors and dividends] are of integer type (int type):

The result is rounded and decimals are rounded off (note: not rounded)

If only one operand among all operands [all divisors and dividends] is real type (real number type: float, double)

The result retains decimals (the format of retaining the number of decimal places is aligned with the type of real number, and it is more accurate if it is more accurate)


Question (4): What should we do when low is equal to high?

In the previous example, we wrote the case where low and high are greater than and less than

So what should we do when low and high are equal?

Try to design a specific example, assuming:

bit sequence 1 2 3
data 22 23 24
pointer low mid high

 So our final conclusion is that:

When low is equal to high:

If the key is not equal to [low and high and mid], then the search fails

If equal, the output pointer

So for this situation, it is more appropriate for us to put him in the while loop


Project 3: (final result)

int Seaarch_Bin(SSTable ST, KeyType key)
//binary:二进制的; 仅基于两个数字的; 二元的; 由两部分组成的;
{
    int low = 1, high = ST.length, mid = (low + high) / 2;
    while (low <= high)
    {
        if (key == ST.R[mid].key)
            return mid;
        else if (key < ST.R[mid].key)
            high = mid - 1;
        else if (key > ST.R[mid].key)//else
            low = mid + 1;

        mid = (low + high) / 2;
    }
    return 0;
}

Attached:

The standard answer version written on the PPT (it does have merits)

It is equivalent to simplifying the program we wrote earlier:

There is no need to assign a value to mid at the beginning, just need to assign a value to mid at the beginning of each cycle

int Seaarch_Bin(SSTable ST, KeyType key)
//binary:二进制的; 仅基于两个数字的; 二元的; 由两部分组成的;
{
    int low = 1, high = ST.length,mid; 
    while (low <= high)
    {
        mid = (low + high) / 2;
        if (key == mid)
            return mid;
        else if (key < ST.R[mid].key)
            high = mid - 1;
        else
            //else if (key > ST.R[mid].key)
            low = mid + 1;   
    }
    return 0;
}

Supplement on PPT: recursive implementation version

int Search_bin(SSTable& S, KeyType e, int low, int high)
{
    if (low > high)
        return -1;
    int mid = (high + low) / 2;
    if (e == S.R[mid].key)
        return mid;
    if (e < S.R[mid].key)
        return Search_bin(S, e, low, mid - 1);
    else
        return Search_bin(S, e, mid + 1, high);
}

 Average search length derivation reference: Chapter 5 "Trees and Binary Trees" P34

Three, block search


Does not examine the code

However, how to implement the block search code can be studied later if you have time, it is quite interesting

Guess you like

Origin blog.csdn.net/Zz_zzzzzzz__/article/details/130122116