0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C 語言數(shù)組的基本結(jié)構(gòu)

科技綠洲 ? 來源:工程師進階筆記 ? 作者:工程師進階筆記 ? 2023-06-22 10:56 ? 次閱讀

數(shù)組是最基本的數(shù)據(jù)結(jié)構(gòu),關(guān)于數(shù)組的面試題也屢見不鮮,本文羅列了一些常見的面試題,僅供參考。目前有以下18道題目。

  • 數(shù)組求和
  • 求數(shù)組的最大值和最小值
  • 求數(shù)組的最大值和次大值
  • 求數(shù)組中出現(xiàn)次數(shù)超過一半的元素
  • 求數(shù)組中元素的最短距離
  • 求兩個有序數(shù)組的共同元素
  • 求三個數(shù)組的共同元素
  • 找出數(shù)組中唯一的重復(fù)元素
  • 找出出現(xiàn)奇數(shù)次的元素
  • 求數(shù)組中滿足給定和的數(shù)對
  • 最大子段和
  • 最大子段積
  • 數(shù)組循環(huán)移位
  • 字符串逆序
  • 組合問題
  • 合并兩個數(shù)組
  • 重排問題
  • 找出絕對值最小的元素

數(shù)組求和

給定一個含有n個元素的整型數(shù)組a,求a中所有元素的和??赡苣鷷X得很簡單,是的,的確簡單,但是為什么還要說呢,原因有二,第一,這道題要求用遞歸法,只用一行代碼。第二,這是我人生中第一次面試時候遇到的題,意義特殊。

分析

簡單說一下,兩種情況

  1. 如果數(shù)組元素個數(shù)為0,那么和為0。
  2. 如果數(shù)組元素個數(shù)為n,那么先求出前n - 1個元素之和,再加上a[n - 1]即可

代碼

// 數(shù)組求和
int sum(int*a, int n)
{
   return n == 0 ? 0 : sum(a, n -1) + a[n -1];
}

求數(shù)組的最大值和最小值

給定一個含有n個元素的整型數(shù)組a,找出其中的最大值和最小值

分析

常規(guī)的做法是遍歷一次,分別求出最大值和最小值,但我這里要說的是分治法(Divide and couquer),將數(shù)組分成左右兩部分,先求出左半部份的最大值和最小值,再求出右半部份的最大值和最小值,然后綜合起來求總體的最大值及最小值。

這是個遞歸過程,對于劃分后的左右兩部分,同樣重復(fù)這個過程,直到劃分區(qū)間內(nèi)只剩一個元素或者兩個元素。

代碼

// 求數(shù)組的最大值和最小值,返回值在maxValue和minValue
void MaxandMin(int *a, int l, int r, int& maxValue, int& minValue)
{
    if(l == r) // l與r之間只有一個元素
    {
        maxValue = a[l] ;
        minValue = a[l] ;
        return ;
    }

    if(l + 1 == r) // l與r之間只有兩個元素
    {
        if(a[l] >= a[r])
        {
            maxValue = a[l] ;
            minValue = a[r] ;
        }
        else
        {
            maxValue = a[r] ;
            minValue = a[l] ;
        }
        return ;
    }

    int m = (l + r) / 2 ; // 求中點

    int lmax ; // 左半部份最大值
    int lmin ; // 左半部份最小值
    MaxandMin(a, l, m, lmax, lmin) ; // 遞歸計算左半部份

    int rmax ; // 右半部份最大值
    int rmin ; // 右半部份最小值
    MaxandMin(a, m + 1, r, rmax, rmin) ; // 遞歸計算右半部份

    maxValue = max(lmax, rmax) ; // 總的最大值
    minValue = min(lmin, rmin) ; // 總的最小值
}

求數(shù)組的最大值和次大值

給定一個含有n個元素的整型數(shù)組,求其最大值和次大值

分析

思想和上一題類似,同樣是用分治法,先求出左邊的最大值leftmax和次大值leftsecond,再求出右邊的最大值rightmax和次大值rightsecond,然后合并,如何合并呢?分情況考慮

1 如果leftmax > rightmax,那么可以肯定leftmax是最大值,但次大值不一定是rightmax,但肯定不是rightsecond,只需將leftsecond與rightmax做一次比較即可。

2 如果rightmax > leftmax,那么可以肯定rightmax是最大值,但次大值不一定是leftmax,但肯定不是leftsecond,所以只需將leftmax與rightsecond做一次比較即可。

注意

這種方法無法處理最大元素有多個的情況,比如3,5,7,7將返回7,7而不是7,5。感謝網(wǎng)友 從無到有靠誰人 指出。

代碼

// 找出數(shù)組的最大值和次大值,a是待查找的數(shù)組,left和right是查找區(qū)間,max和second存放結(jié)果
void MaxandMin(int a[], int left, int right, int&max, int&second)
{
    if(left == right)
    {
        max = a[left] ;
        second =  INT_MIN;
    }
    elseif(left +1== right)
    {
        max = a[left] > a[right] ? a[left] : a[right] ;
        second = a[left] < a[right] ? a[left] : a[right] ;
    }
    else
    {
        int mid = left + (right - left) /2 ;

        int leftmax ;
        int leftsecond ;
        MaxandMin(a, left, mid, leftmax, leftsecond) ;

        int rightmax ;
        int rightsecond ;
        MaxandMin(a, mid +1, right, rightmax, rightsecond) ;

        if (leftmax > rightmax)
        {
            max = leftmax ;
            second = leftsecond > rightmax ? leftsecond : rightmax ;
        }
        else
        {
            max = rightmax ;
            second = leftmax < rightsecond ? rightsecond : leftmax ;
        }
    }
}

求數(shù)組中出現(xiàn)次數(shù)超過一半的元素

給定一個n個整型元素的數(shù)組a,其中有一個元素出現(xiàn)次數(shù)超過n / 2,求這個元素。據(jù)說是百度的一道題

分析

設(shè)置一個當(dāng)前值和當(dāng)前值的計數(shù)器,初始化當(dāng)前值為數(shù)組首元素,計數(shù)器值為1,然后從第二個元素開始遍歷整個數(shù)組,對于每個被遍歷到的值a[i]

1 如果a[i]==currentValue,則計數(shù)器值加1

2 如果a[i] != currentValue, 則計數(shù)器值減1,如果計數(shù)器值小于0,則更新當(dāng)前值為a[i],并將計數(shù)器值重置為1

代碼

// 找出數(shù)組中出現(xiàn)次數(shù)超過一半的元素
int Find(int* a, int n)
{
    int curValue = a[0] ;
    int count = 1 ;

    for (int i = 1; i < n; ++i)
    {
        if (a[i] == curValue)
            count++ ;
        else
        {
            count-- ;
            if (count < 0)
            {
                curValue = a[i] ;
                count = 1 ;
            }
        }
    }

    return curValue ;
}

另一個方法是先對數(shù)組排序,然后取中間元素即可,因為如果某個元素的個數(shù)超過一半,那么數(shù)組排序后該元素必定占據(jù)數(shù)組的中間位置。

求數(shù)組中元素的最短距離

給定一個含有n個元素的整型數(shù)組,找出數(shù)組中的兩個元素x和y使得abs(x - y)值最小

分析

先對數(shù)組排序,然后遍歷一次即可

代碼

int compare(const void* a, const void* b)
{
    return *(int*)a - *(int*)b ;
}

// 求數(shù)組中元素的最短距離
void MinimumDistance(int* a, int n)
{
    // Sort
    qsort(a, n, sizeof(int), compare) ;

    int i ; // Index of number 1
    int j ; // Index of number 2

    int minDistance = numeric_limits< int >::max() ;
    for (int k = 0; k < n - 1; ++k)
    {
        if (a[k + 1] - a[k] < minDistance)
        {
            minDistance = a[k + 1] - a[k] ;
            i = a[k] ;
            j = a[k + 1] ;
        }
    }

    cout < < "Minimum distance is: " < < minDistance < < endl ;
    cout < < "i = " < < i < < " j = " < < j < < endl ;
}

求兩個有序數(shù)組的共同元素

給定兩個含有n個元素的有序(非降序)整型數(shù)組a和b,求出其共同元素,比如

a = 0, 1, 2, 3, 4

b = 1, 3, 5, 7, 9

輸出 1, 3

分析

充分利用數(shù)組有序的性質(zhì),用兩個指針i和j分別指向a和b,比較a[i]和b[j],根據(jù)比較結(jié)果移動指針,則有如下三種情況

  1. a[i] < b[j],則i增加1,繼續(xù)比較
  2. a[i] == b[j],則i和j皆加1,繼續(xù)比較
  3. a[i] < b[j],則j加1,繼續(xù)比較

重復(fù)以上過程直到i或j到達數(shù)組末尾。

代碼

// 找出兩個數(shù)組的共同元素
void FindCommon(int* a, int* b, int n)
{
    int i = 0;
    int j = 0 ;

    while (i < n && j < n)
    {
        if (a[i] < b[j])
            ++i ;
        else if(a[i] == b[j])
        {
            cout < < a[i] < < endl ;
            ++i ;
            ++j ;
        }
        else// a[i] > b[j]
            ++j ;
    }
}

這到題還有其他的解法,比如對于a中任意一個元素,在b中對其進行Binary Search,因為a中有n個元素,而在b中進行Binary Search需要logn。所以找出全部相同元素的時間復(fù)雜度是O(nlogn)。

另外,上面的方法,只要b有序即可,a是否有序無所謂,因為我們只是在b中做Binary Search。

如果a也有序的話,那么再用上面的方法就有點慢了,因為如果a中某個元素在b中的位置是k的話,那么a中下一個元素在b中的位置一定位于k的右側(cè),所以本次的搜索空間可以根據(jù)上次的搜索結(jié)果縮小,而不是仍然在整個b中搜索。也即如果a和b都有序的話,代碼可以做如下修改,記錄上次搜索時b中元素的位置,作為下一次搜索的起始點。

求三個數(shù)組的共同元素

給定三個含有n個元素的整型數(shù)組a,b和c,求他們最小的共同元素。

分析

如果三個數(shù)組都有序,那么可以設(shè)置三個指針指向三個數(shù)組的頭部,然后根據(jù)這三個指針?biāo)傅闹颠M行比較來移動指針,直道找到共同元素。

代碼

// 三個數(shù)組的共同元素-只找最小的
void FindCommonElements(int a[], int b[], int c[], int x, int y, int z)
{
    for(int i = 0, j = 0, k = 0; i < x && j < y && k < z;)
    {
        if(a[i] < b[j])
        {
            i++ ;
        }
        else // a[i] >= b[j]
        {
            if(b[j] < c[k])
            {
                j++ ;
            }
            else // b[j] >= c[k]
            {
                if(c[k] < a[i])
                {
                    k++ ;
                }
                else // c[k] >= a[i]
                {
                    cout < < c[k] < < endl ;
                    return ;
                }
            }
        }
    }

    cout < < "Not found!" < < endl ;
}

如果三個數(shù)組都無序,可以先對a, b進行排序,然后對c中任意一個元素都在b和c中做二分搜索。

代碼

// 找出三個數(shù)組的共同元素
// O(NlogN)
int UniqueCommonItem(int *a, int *b, int *c, int n)
{
    // sort array a
    qsort(a, n, sizeof(int), compare) ; // NlogN

    // sort array b
    qsort(b, n, sizeof(int), compare) ; // NlogN

    // for each element in array c, do a binary search in a and b
    // This is up to a complexity of N*2*logN
    for (int i = 0; i < n; i++)
    {
        if(BinarySearch(a, n, c[i]) && BinarySearch(b, n, c[i]))
            return c[i] ;
    }

    return - 1 ; // not found
}

也可以對a進行排序,然后對于b和c中任意一個元素都在a中進行二分搜索,但是這樣做是有問題的,你看出來了么?感謝網(wǎng)友yy_5533指正。

代碼

// 找出三個數(shù)組唯一的共同元素
// O(NlogN)
int UniqueCommonItem1(int *a, int *b, int *c, int n)
{
    // sort array a
    qsort(a, n, sizeof(int), compare) ; // NlogN

    // Space for time
    bool *bb = new bool[n] ;
    memset(bb, 0, n) ;

    bool *bc = new bool[n] ;
    memset(bb, 0, n) ;

    // for each element in b, do a BS in a and mark all the common element
    for (int i = 0; i < n; i++) // NlogN
    {
        if(BinarySearch(a, n, b[i]))
            bb[i] = true ;
    }

    // for each element in c, do a BS only if b[i] is true
    for (int i = 0; i < n; i++) // NlogN
    {
        if(b[i] && BinarySearch(a, n, c[i]))
            return c[i] ;
    }

    return - 1 ; // not found
}

排序和二分搜索代碼如下

// Determine whether a contains value k
bool BinarySearch(int *a, int n, int k)
{
    int left = 0 ;
    int right = n - 1 ;
    while (left <= right)
    {
        int mid = (left + right) ;

        if(a[mid] < k)
            left = mid + 1 ;
        if(a[mid] == k)
            return true ;
        else
            right = mid - 1 ;
    }

    return false ;
}

// Compare function for qsort
int compare(const void* a, const void* b)
{
    return *(int*)a - *(int*)b ;
}

小小總結(jié)一下,對于在數(shù)組中進行查找的問題,可以分如下兩種情況處理

  1. 如果給定的數(shù)組有序,那么首先應(yīng)該想到Binary Search,所需O(logn)
  2. 如果給定的數(shù)組無序,那么首先應(yīng)該想到對數(shù)組進行排序,很多排序算法都能在O(nlogn)時間內(nèi)對數(shù)組進行排序,然后再使用二分搜索,總的時間復(fù)雜度仍是O(nlogn)。

如果能做到以上兩點,大多數(shù)關(guān)于數(shù)組的查找問題,都能迎刃而解。

找出數(shù)組中唯一的重復(fù)元素

給定含有1001個元素的數(shù)組,其中存放了1-1000之內(nèi)的整數(shù),只有一個整數(shù)是重復(fù)的,請找出這個數(shù)

分析

求出整個數(shù)組的和,再減去1-1000的和

代碼

找出出現(xiàn)奇數(shù)次的元素

給定一個含有n個元素的整型數(shù)組a,其中只有一個元素出現(xiàn)奇數(shù)次,找出這個元素。這道題實際上是一個變種,原題是找出數(shù)組中唯一一個出現(xiàn)一次的元素,下面的方法可以同時解決這兩道提。所以題目就用這個廣義的吧。

分析

因為對于任意一個數(shù)k,有k ^ k = 0,k ^ 0 = k,所以將a中所有元素進行異或,那么個數(shù)為偶數(shù)的元素異或后都變成了0,只留下了個數(shù)為奇數(shù)的那個元素。

代碼

int FindElementWithOddCount(int*a, int n)
{
   int r = a[0] ;

   for (int i =1; i < n; ++i)
   {
      r ^= a[i] ;
   }

   return r ;
}

求數(shù)組中滿足給定和的數(shù)對

給定兩個有序整型數(shù)組a和b,各有n個元素,求兩個數(shù)組中滿足給定和的數(shù)對,即對a中元素i和b中元素j,滿足i + j = d(d已知)

分析

兩個指針i和j分別指向數(shù)組的首尾,然后從兩端同時向中間遍歷。

代碼

// 找出滿足給定和的數(shù)對
void FixedSum(int* a, int* b, int n, int d)
{
    for (int i = 0, j = n - 1; i < n && j >= 0)
    {
        if (a[i] + b[j] < d)
            ++i ;
        else if (a[i] + b[j] == d)
        {
            cout < < a[i] < < ", " < < b[j] < < endl ;
            ++i ;
            --j ;
        }
        else // a[i] + b[j] > d
            --j ;
    }
}

最大子段和

給定一個整型數(shù)組a,求出最大連續(xù)子段之和,如果和為負數(shù),則按0計算,比如1, 2, -5, 6, 8則輸出6 + 8 = 14

分析

編程珠璣上的經(jīng)典題目,不多說了。

代碼

// 子數(shù)組的最大和
int Sum(int* a, int n)
{
    int curSum = 0;
    int maxSum = 0;
    for (int i = 0; i < n; i++)
    {
        if (curSum + a[i] < 0)
            curSum = 0;
        else
        {
            curSum += a[i] ;
            maxSum = max(maxSum, curSum);
        }
    }
    return maxSum;
}

最大子段積

給定一個整型數(shù)組a,求出最大連續(xù)子段的乘積,比如 1, 2, -8, 12, 7則輸出12 * 7 = 84

分析

與最大子段和類似,注意處理負數(shù)的情況

代碼

// 子數(shù)組的最大乘積
int MaxProduct(int *a, int n)
{
    int maxProduct = 1; // max positive product at current position
    int minProduct = 1; // min negative product at current position
    int r = 1; // result, max multiplication totally

    for (int i = 0; i < n; i++)
    {
        if (a[i] > 0)
        {
            maxProduct *= a[i];
            minProduct = min(minProduct * a[i], 1);
        }
        else if (a[i] == 0)
        {
            maxProduct = 1;
            minProduct = 1;
        }
        else // a[i] < 0
        {
            int temp = maxProduct;
            maxProduct = max(minProduct * a[i], 1);
            minProduct = temp * a[i];
        }

        r = max(r, maxProduct);
    }

    return r;
}

數(shù)組循環(huán)移位

將一個含有n個元素的數(shù)組向右循環(huán)移動k位,要求時間復(fù)雜度是O(n),且只能使用兩個額外的變量,這是在微軟的編程之美上看到的一道題

分析

比如數(shù)組 1 2 3 4循環(huán)右移1位 將變成 4 1 2 3, 觀察可知1 2 3 的順序在移位前后沒有改變,只是和4的位置交換了一下,所以等同于1 2 3 4 先劃分為兩部分

1 2 3 | 4,然后將1 2 3逆序,再將4 逆序 得到 3 2 1 4,最后整體逆序 得到 4 1 2 3

代碼

// 將buffer中startend之間的元素逆序
void Reverse( int buffer[], int start, int end )
{
    while ( start < end )
    {
        int temp = buffer[ start ] ;
        buffer[ start++ ] = buffer[ end ] ;
        buffer[ end-- ] = temp ;
    }
}

// 將含有n個元素的數(shù)組buffer右移k位
void Shift( int buffer[], int n, int k )
{
    k %= n ;

    Reverse( buffer, 0, n - k - 1) ;
    Reverse( buffer, n - k, n - 1 ) ;
    Reverse( buffer, 0, n - 1 ) ;
}

稍微擴展一下,如果允許分配額外的數(shù)組,那么定義一個新的數(shù)組,然后將移位后的元素直接存入即可,也可以使用隊列,將移動后得元素出對,再插入隊尾即可.

字符串逆序

給定一個含有n個元素的字符數(shù)組a,將其原地逆序。

分析

可能您覺得這不是關(guān)于數(shù)組的,而是關(guān)于字符串的。是的。但是別忘了題目要求的是原地逆序,也就是不允許額外分配空間,那么參數(shù)肯定是字符數(shù)組形式,因為字符串是不能被修改的(這里只C/C++中的字符串常量)。

所以,和數(shù)組有關(guān)了吧,只不過不是整型數(shù)組,而是字符數(shù)組。用兩個指針分別指向字符數(shù)組的首位,交換其對應(yīng)的字符,然后兩個指針分別向數(shù)組中央移動,直到交叉。

代碼

// 字符串逆序
void Reverse(char*a, int n)
{
   int left =0;
   int right = n -1;

   while (left < right)
   {
     char temp = a[left] ;
     a[left++] = a[right] ;
     a[right--] = temp ;
   }
}

組合問題

給定一個含有n個元素的整型數(shù)組a,從中任取m個元素,求所有組合。比如下面的例子

a = 1, 2, 3, 4, 5

m = 3

輸出

1 2 3, 1 2 4, 1 2 5, 1 3 4, 1 3 5, 1 4 5

2 3 4, 2 3 5, 2 4 5
3 4 5

分析

典型的排列組合問題,首選回溯法,為了簡化問題,我們將a中n個元素值分別設(shè)置為1-n

代碼

// n選m的所有組合
int buffer[100] ;

void PrintArray(int *a, int n)
{
    for (int i = 0; i < n; ++i)
        cout < < a[i] < < "";
    cout < < endl ;
}

bool IsValid(int lastIndex, int value)
{
    for (int i = 0; i < lastIndex; i++)
    {
        if (buffer[i] >= value)
            return false;
    }
    return true;
}

void Select(int t, int n, int m)
{
    if (t == m)
        PrintArray(buffer, m);
    else
    {
        for (int i = 1; i <= n; i++)
        {
            buffer[t] = i;
            if (IsValid(t, i))
                Select(t + 1, n, m);
        }
    }
}

合并兩個數(shù)組

給定含有n個元素的兩個有序(非降序)整型數(shù)組a和b。合并兩個數(shù)組中的元素到整型數(shù)組c,要求去除重復(fù)元素并保持c有序(非降序)。例子如下

a = 1, 2, 4, 8

b = 1, 3, 5, 8

c = 1, 2, 3, 4, 5, 8

分析

利用合并排序的思想,兩個指針i,j和k分別指向數(shù)組a和b,然后比較兩個指針對應(yīng)元素的大小,有以下三種情況

  1. a[i] < b[j],則c[k] = a[i]。
  2. a[i] == b[j],則c[k]等于a[i]或b[j]皆可。
  3. a[i] > b[j],則c[k] = b[j]。

重復(fù)以上過程,直到i或者j到達數(shù)組末尾,然后將剩下的元素直接copy到數(shù)組c中即可

代碼

// 合并兩個有序數(shù)組
void Merge(int *a, int *b, int *c, int n)
{
    int i = 0 ;
    int j = 0 ;
    int k = 0 ;

    while (i < n && j < n)
    {
        if (a[i] < b[j])// 如果a的元素小,則插入a中元素到c
        {
            c[k++] = a[i] ;
            ++i ;
        }
        else if (a[i] == b[j])// 如果a和b元素相等,則插入二者皆可,這里插入a
        {
            c[k++] = a[i] ;
            ++i ;
            ++j ;
        }
        else // a[i] > b[j] // 如果b中元素小,則插入b中元素到c
        {
            c[k++] = b[j] ;
            ++j ;
        }
    }

    if (i == n) // 若a遍歷完畢,處理b中剩下的元素
    {
        for (int m = j; m < n; ++m)
            c[k++] = b[m] ;
    }
    else//j == n, 若b遍歷完畢,處理a中剩下的元素
    {
        for (int m = i; m < n; ++m)
            c[k++] = a[m] ;
    }
}

重排問題

給定含有n個元素的整型數(shù)組a,其中包括0元素和非0元素,對數(shù)組進行排序,要求:

  1. 排序后所有0元素在前,所有非零元素在后,且非零元素排序前后相對位置不變
  2. 不能使用額外存儲空間

例子如下

輸入 0, 3, 0, 2, 1, 0, 0

輸出 0, 0, 0, 0, 3, 2, 1

分析

此排序非傳統(tǒng)意義上的排序,因為它要求排序前后非0元素的相對位置不變,或許叫做整理會更恰當(dāng)一些。我們可以從后向前遍歷整個數(shù)組,遇到某個位置i上的元素是非0元素時,如果a[k]為0,則將a[i]賦值給a[k],a[k]賦值為0。實際上i是非0元素的下標(biāo),而k是0元素的下標(biāo)

代碼

void Arrange(int* a, int n)
{
    int k = n -1 ;
    for (int i = n -1; i >=0; --i)
    {
        if (a[i] !=0)
        {
            if (a[k] ==0)
            {
                a[k] = a[i] ;
                a[i] =0 ;
            }
            --k ;
        }
    }
}

找出絕對值最小的元素

給定一個有序整數(shù)序列(非遞減序),可能包含負數(shù),找出其中絕對值最小的元素,比如給定序列 -5, -3, -1, 2, 8 則返回1。

分析

由于給定序列是有序的,而這又是搜索問題,所以首先想到二分搜索法,只不過這個二分法比普通的二分法稍微麻煩點,可以分為下面幾種情況

  • 如果給定的序列中所有的數(shù)都是正數(shù),那么數(shù)組的第一個元素即是結(jié)果。
  • 如果給定的序列中所有的數(shù)都是負數(shù),那么數(shù)組的最后一個元素即是結(jié)果。
  • 如果給定的序列中既有正數(shù)又有負數(shù),那么絕對值得最小值一定出現(xiàn)在正數(shù)和負數(shù)的連接處。

為什么?

因為對于負數(shù)序列來說,右側(cè)的數(shù)字比左側(cè)的數(shù)字絕對值小,如上面的-5, -3, -1, 而對于整整數(shù)來說,左邊的數(shù)字絕對值小,比如上面的2, 8,將這個思想用于二分搜索,可先判斷中間元素和兩側(cè)元素的符號,然后根據(jù)符號決定搜索區(qū)間,逐步縮小搜索區(qū)間,直到只剩下兩個元素。

代碼

單獨設(shè)置一個函數(shù)用來判斷兩個整數(shù)的符號是否相同。

bool SameSign(int a, int b)
{
    if (a * b > 0)
        return true;
    else
        return false;
}

主函數(shù)代碼。

// 找出一個非遞減序整數(shù)序列中絕對值最小的數(shù)
int MinimumAbsoluteValue(int* a, int n)
{
    // Only one number in array
    if (n ==1)
    {
        return a[0] ;
    }

    // All numbers in array have the same sign
    if (SameSign(a[0], a[n -1]))
    {
        return a[0] >=0? a[0] : a[n -1] ;
    }

    // Binary search
    int l =0 ;
    int r = n -1 ;

    while(l < r)
    {
        if (l +1== r)
        {
            return abs(a[l]) < abs(a[r]) ? a[l] : a[r] ;
        }

        int m = (l + r) /2 ;

        if (SameSign(a[m], a[r]))
        {
            r = m -1;
            continue;
        }
        if (SameSign(a[l], a[m]))
        {
            l = m +1 ;
            continue;
        }
    }
}

這段代碼是有問題的,感謝網(wǎng)友lingyunfish的指正,你看出來了么?修改后的代碼如下:

// 找出一個非遞減序整數(shù)序列中絕對值最小的數(shù)
int MinimumAbsoluteValue(int* a, int n)
{
    // Only one number in array
    if (n ==1)
    {
        return a[0] ;
    }

    // All numbers in array have the same sign
    if (SameSign(a[0], a[n -1]))
    {
        return a[0] >=0? a[0] : a[n -1] ;
    }

    // Binary search
    int l =0 ;
    int r = n -1 ;

    while(l < r)
    {
        if (l + 1 == r)
        {
            return abs(a[l]) < abs(a[r]) ? a[l] : a[r] ;
        }

        int m = (l + r) /2 ;

        if (SameSign(a[m], a[r]))
        {
            r = m;
            continue;
        }
        else
        {
            l = m ;
            continue;
        }
    }
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4694

    瀏覽量

    68075
  • 數(shù)組
    +關(guān)注

    關(guān)注

    1

    文章

    411

    瀏覽量

    25858
收藏 人收藏

    評論

    相關(guān)推薦

    C語言數(shù)組詳解

    介紹C語言數(shù)組的知識點。
    的頭像 發(fā)表于 05-19 10:15 ?6211次閱讀

    C語言數(shù)組結(jié)構(gòu)體的內(nèi)存表示和布局

    C語言中,數(shù)組結(jié)構(gòu)體都可以代表一塊內(nèi)存,但為什么結(jié)構(gòu)體可以直接賦值,而數(shù)組不可以?這個問題涉及
    發(fā)表于 08-28 10:54 ?1302次閱讀

    C語言數(shù)組的用法

    C語言數(shù)組是一種數(shù)據(jù)結(jié)構(gòu),它可以存儲多個相同類型的數(shù)據(jù),例如整數(shù),字符,浮點數(shù)等。數(shù)組的每個元素都有一個索引,用來表示它在
    的頭像 發(fā)表于 11-24 17:48 ?1140次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>中<b class='flag-5'>數(shù)組</b>的用法

    C語言教程之查找數(shù)組中的最值

    C語言教程之查找數(shù)組中的最值,很好的C語言資料,快來學(xué)習(xí)吧。
    發(fā)表于 04-25 15:13 ?0次下載

    C語言學(xué)習(xí)數(shù)組的筆記

    C語言學(xué)習(xí)數(shù)組的筆記
    發(fā)表于 12-17 16:04 ?0次下載

    為什么C語言函數(shù)不能返回數(shù)組

    C語言函數(shù)可以返回指針、結(jié)構(gòu)體,為什么不能返回數(shù)組? 下面一步一步來分析: 1 函數(shù)不能返回數(shù)組C
    的頭像 發(fā)表于 03-29 11:18 ?1944次閱讀

    C語言指針和數(shù)組的區(qū)別

    C語言教程中我們使用通過數(shù)組名通過偏移和指針偏移都可以遍歷數(shù)組,那么指針和數(shù)組到底有什么區(qū)別??
    的頭像 發(fā)表于 07-18 16:29 ?1840次閱讀

    C語言總結(jié)_數(shù)組全方位練習(xí)

    C語言數(shù)組的練習(xí)題:涉及到數(shù)組插入、數(shù)組刪除、數(shù)組下標(biāo)數(shù)據(jù)的左移右移、
    的頭像 發(fā)表于 08-14 09:34 ?837次閱讀

    C語言總結(jié)_數(shù)組知識

    當(dāng)前文章復(fù)盤C語言數(shù)組數(shù)組定義規(guī)則、數(shù)組空間類型、數(shù)組下標(biāo)使用、
    的頭像 發(fā)表于 08-14 09:38 ?1246次閱讀

    C語言_數(shù)組的查找、替換、排序、拼接

    這篇文章主要是總結(jié)C語言的位運算幾個實戰(zhàn)例子,接著介紹數(shù)組的基本定義用法、數(shù)組排序、插入、拼接、刪除、字符串查找替換等。
    的頭像 發(fā)表于 08-14 09:48 ?2471次閱讀

    C語言-數(shù)組

    C語言數(shù)組是一個同類型數(shù)據(jù)的集合,主要用來存儲一堆同類型的數(shù)據(jù)。
    的頭像 發(fā)表于 08-14 09:59 ?1221次閱讀

    C語言數(shù)組是什么

    C 語言支持數(shù)組數(shù)據(jù)結(jié)構(gòu),它可以存儲一個固定大小的相同類型元素的順序集合。數(shù)組是用來存儲一系列數(shù)據(jù),但它往往被認為是一系列相同類型的變量。
    的頭像 發(fā)表于 02-17 14:29 ?1231次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>數(shù)組</b>是什么

    C程序設(shè)計基礎(chǔ)-數(shù)組結(jié)構(gòu)

    數(shù)組結(jié)構(gòu)體和指針是C語言里面最難的部分,如果在編程中可以熟練的運用這三樣工具,會大大地提高開發(fā)效率,簡化程序結(jié)構(gòu),提成代碼運行速度。
    的頭像 發(fā)表于 03-02 10:10 ?840次閱讀
    <b class='flag-5'>C</b>程序設(shè)計基礎(chǔ)-<b class='flag-5'>數(shù)組</b>與<b class='flag-5'>結(jié)構(gòu)</b>體

    C語言如何創(chuàng)建數(shù)組

    用法和注意事項。 要創(chuàng)建一個數(shù)組,首先需要確定數(shù)組的數(shù)據(jù)類型和大小。C語言中的數(shù)據(jù)類型包括基本數(shù)據(jù)類型(如整數(shù)、浮點數(shù)、字符等)以及派生數(shù)據(jù)類型(如
    的頭像 發(fā)表于 11-24 10:08 ?1521次閱讀

    c語言數(shù)組怎么定義

    C語言中,數(shù)組是一種用來存儲相同類型元素的數(shù)據(jù)結(jié)構(gòu)。它可以存儲多個元素,并通過一個共同的名稱來引用這些元素。數(shù)組是一種很重要的數(shù)據(jù)
    的頭像 發(fā)表于 11-24 10:11 ?2551次閱讀