如何使用二进制搜索将元素插入到排序向量中

时间:2017-09-23 04:42:05

标签: c++ sorting vector

你好,我有一个问题,我不知道我使用二进制搜索插入矢量的实现是否正确。 我有两个向量一个存储类对象。第二个是假设要排序的那个。第二个向量保存第一个向量的索引,这些索引假设按字典顺序排列(从小到大)。我试图让我的程序运行O(log(n))。这就是我拥有的......

void Trendtracker:: add_hashtag(string ht)
{

    Entry tweet;
    tweet.count = 0;
    tweet.hashtag = ht;
    if (E.empty())
    {
        E.push_back(tweet);
        S.push_back(0);
    }


    int l, m, r;
    l = 0;
    r = S.size() -1;

    while (l < r)
    {
        m =(l+r)/2;
        if(E[S[m]].hashtag == ht)//found #1
            return;
        else if (E[S[m]].hashtag < ht)// searches right
            l = m +1;
        else
            r = m-1; // searches left

    }

    if( l ==r && E[S[l]].hashtag == tweet.hashtag)// found #2
        return;

    E.push_back(tweet);

    //if not found and lower than the lowest
    if(l==0 && ht < E[S[l]].hashtag)
    {
        //S[0]= E.size()-1;
        S.insert(S.begin(), E.size()-1);
    }

    // if not found but is higher than highest
    else if(l == S.size()-1 && E[S[l]].hashtag < ht)
    {
        S.push_back(E.size()-1);
    }

    // if new hashtag goes in the second index
    else if(l==0&& r==0 && E[S[r]].hashtag< ht)
    {

        S.insert(S.begin()+1, E.size()-1);
    }

    // if not found and l & r are somewhere in the middle
    else
    {

        S.insert(S.begin()+l, E.size()-1);
    }
}

2 个答案:

答案 0 :(得分:0)

如果您经常使用容器在中间插入/移除,那么std::vector可能不是您最好的选择。

考虑一下:std::vector将元素存储在连续的内存中,因此每次要在其中间插入元素时,都会移动后面的所有元素。查找起来更快(如果它已经排序,则更快)但是插入时的开销是需要注意的。

您可以查看实现链表的列表或其他类型的容器,因为插入就像创建节点一样简单,更改元素之前的nextprev指针,元素本身和之后的元素。

希望有所帮助

答案 1 :(得分:0)

算法的症结在于:

1)使用二进制搜索检查中间索引值

  a) If the value to be inserted is less than mid value - check the (mid - 1) index if it is a valid index. If mid -1 is also less then you have to insert at current mid position.Otherwise, Change high to mid -1 and continue to search left
  b) If the value to be inserted is greater than mid value - check the (mid + 1) index if it is a valid index. If mid + 1 is also greater then you have to insert at mid + 1 position. Otherwise, change low to mid + 1 and continue to search right
  c) Handle overflow cases

以下是使用二进制搜索进行基于向量的插入的示例代码:

#include <iostream>
#include <vector>

using namespace std;

void insert(vector<int> &arr,int value)
{
    int low = 0;
    int high = (int)(arr.size() - 1);
    int mid = low+(high - low)/2;
    int indexToInsert = -1;
    while(low<=high)
    {
        if(mid < 0 || mid > arr.size()-1)
            break;
        if(value < arr[mid])
        {
            //check if previous index is valid and lesser than value
            if(mid-1 >= 0)
            {
                if(arr[mid-1]<value)
                {
                    indexToInsert = mid;
                    break;
                }
            }
            high = mid - 1;
        }
        else if(value > arr[mid])
        {
            //check if next index is valid and greater than value
            if(mid+1 < arr.size())
            {
                if(arr[mid+1]>value)
                {
                    indexToInsert = mid+1;
                    break;
                }
            }
            low = mid + 1;
        }
        mid = low+(high - low)/2;
    }
    if(indexToInsert == -1)
    {
        if(mid<=0)
            indexToInsert = 0;
        else if (mid>=arr.size())
            indexToInsert = (int)(arr.size());
    }

    arr.insert(arr.begin() + indexToInsert, value);
}

void printVec(vector<int> vec)
{
    for(int i=0;i<vec.size();i++)
    {
        cout<<vec[i]<<" ";
    }
    cout<<"\n";
}

int main(int argc, const char * argv[]) {

    vector<int> vec;
    for(int i=1;i<10;i++)
    {
        vec.push_back(i+(i*1));//used to create a ascending sorted array
        cout<<vec[i-1]<<" ";
    }
    cout<<"\n";

    insert(vec, 3);
    cout<<"After insertion of 3: \n";
    printVec(vec);

    insert(vec, 25);
    cout<<"After insertion of 25: \n";
    printVec(vec);

    insert(vec, 11);
    cout<<"After insertion of 11: \n";
    printVec(vec);

    insert(vec, 1);
    cout<<"After insertion of 1: \n";
    printVec(vec);
    return 0;
}

请告诉我其中是否有错误。

相关问题