1. 程式人生 > >對整數陣列進行二分查詢;傳陣列指標會丟失陣列大小資訊。

對整數陣列進行二分查詢;傳陣列指標會丟失陣列大小資訊。

二分查詢是一個迭代(iterator)過程,它所搜尋的物件是一個有序(這裡用的升序)的陣列。

思想:

1. 判斷左右指標是否合理:若不合理則迭代結束;否則進行2。

2. 判斷以左右指標批向的點為邊界時,中間點是否與查詢點相等:若相等,找到目標,結束;否則,進行3。

3. 判斷左右指標與中間點的大小關係(經過2,已經判斷過相等的情況):中間點大於目標,右指標移到中間點左一位置;中間點小於目標,左指標移到中間點右一位置。返回1。

程式碼實現:

int main ()
{
    int a_size = 30;
    int a[30] = {64, 84, 42, 4, 95, 35, 16, 33, 82, 16, 95, 28, 63, 35, 90, 11, 49, 77, 91, 2};
    
    sort(a, a + a_size); // 給陣列排一下序
    int X = 16; // 待查詢數

    int left = 0, right = a_size - 1; // 初始化左右指標
    
    for (int i = 0; i < a_size; i++) // 打印出排序後的陣列。
    {
        cout<<"Index:["<<i<<"]:"<<a[i]<<endl;
    }
    cout<<endl;
    while(1)
    {
        if (left > right) // 沒找到目標
            break;
        int mid = (left + right)/2; // 折半
        if(a[mid] == X)
        {
            cout<<"Find "<<X<<" in position: "<<mid<<"\tIndex: "<<mid - 1<<endl; // 找到目標,給出資訊
            return mid;
        }
        else if (a[mid] > X) // 中間數大於目標,左指標移到中間數右一位置
        {
            left = mid +1; 
        }
        else // 中間數小於目標,右指標移到中間數左一位置
            right = mid - 1;
    }
    cout<<X<<" not in array!"<<endl;
    return 0;
}


下面說一個在與二分查演算法找無關,而是在實現過程中遇到的一個問題:傳陣列指標會丟失陣列大小資訊。

int findX(int *a, int X)
{
    int a_size = (sizeof(a)/sizeof(*a));
    cout<<"sizeof(a):"<<sizeof(a)<<endl; // ? sizeof(a) == 8 is true? Sizeof on array function parameter will return size of 'int *' instead of 'int []'
    // 這裡得到的size是指標的大小。也就是說,現在指向陣列a的指標變數的大小是sizeof(a).
    cout<<"sizeof(*a):"<<sizeof(*a)<<endl;
    cout<<a[2]<<endl;
    int left = 0, right = a_size - 1;
    sort(a, a + a_size);
//    cout<<*a<<endl;
    cout<<"size of array:"<<a_size<<endl;
    for (int i = 0; i < a_size; i++) {
        cout<<a[i]<<"\t";
    }
    cout<<endl;
    while(1)
    {
        if (left > right)
            break;
        int mid = (left + right)/2;
        if(a[mid] == X)
        {
            cout<<" find "<<X<<" in position: "<<mid<<endl;
            return mid;
        }
        else if (a[mid] > X)
        {
            left = mid +1;
        }
        else
            right = mid - 1;
    }
    cout<<X<<" not in array!"<<endl;
    return -1;
}

int main ()
{
    int a[30] = {64, 84, 42, 4, 95, 35, 16, 33, 82, 16, 95, 28, 63, 35, 90, 11, 49, 77, 91, 2};
    cout<<"sizeof(a):"<<sizeof(a)<<endl;
    cout<<"sizeof(*a):"<<sizeof(*a)<<endl;
    cout<<findX(a, 5)<<endl;
    return 0;
}
		

解決這個問題可以用function template:
template <typename T, int N> // 在這裡相當於定義兩個待賦值的變數,一個是資料型別變數T,一個是整數N
int findX(T (&a)[N], int X) //  在這裡把陣列int a[n]的資料型別int賦給T, 陣列大小賦給N
{
    int a_size = N;
    cout<<"sizeof(a):"<<sizeof(a)<<endl; // 現在就沒有問題了。
    cout<<"sizeof(*a):"<<sizeof(*a)<<endl;
    cout<<a[2]<<endl;
    int left = 0, right = a_size - 1;
    sort(a, a + a_size);
//    cout<<*a<<endl;
    cout<<"size of array:"<<a_size<<endl;
    for (int i = 0; i < a_size; i++) {
        cout<<a[i]<<"\t";
    }
    cout<<endl;
    while(1)
    {
        if (left > right)
            break;
        int mid = (left + right)/2;
        if(a[mid] == X)
        {
            cout<<" find "<<X<<" in position: "<<mid<<endl;
            return mid;
        }
        else if (a[mid] > X)
        {
            left = mid +1;
        }
        else
            right = mid - 1;
    }
    cout<<X<<" not in array!"<<endl;
    return -1;
}

int main ()
{
//    test_point();
//    int a[20]={2,4,1,23,5,76,0,43,24,65};
    int a[30] = {64, 84, 42, 4, 95, 35, 16, 33, 82, 16, 95, 28, 63, 35, 90, 11, 49, 77, 91, 2};
    cout<<"sizeof(a):"<<sizeof(a)<<endl;
    cout<<"sizeof(*a):"<<sizeof(*a)<<endl;
    cout<<findX(a, 5)<<endl;
    cout<<"test"<<endl;
    int a_size = (sizeof(a)/sizeof(*a));
    return 0;
}