通过“inorder”和“reverse inorder”方法同时遍历二进制搜索树的多线程方法,比较元素对

时间:2015-03-06 11:09:08

标签: c++ multithreading mutex binary-search-tree inorder

在一些情况下,能够比较二进制搜索树中的最后一个元素和第一个元素,元素对,将被证明是有用的。

例如:查找总计为给定数字的2个元素。 (最快的方法是尝试添加最小和最大的数字,然后根据与给定数字相比得到的总和推进每一端)

^我知道这可以通过使用2个堆栈以迭代方式遍历树来完成。我只是在考虑是否有一种方法可以使用 2个线程来做这样的事情:

pthread_mutex_t MTree1, Mtree2;
pthread_t thread[2];
pthread_attr attr;
int data1, data2;
int tempInorder, tempRevInorder;
int requiredSUM

void mergBST(node*root)
{
    pthread_mutex_init(&Mtree1, NULL);
    pthread_mutex_init(&Mtree2, NULL);
    pthread_attr_setdetachestate(&attr,PTHREAD_CREATE_JOINABLE);

    pthread_create(&thread[0],&attr, mergeBSTImplInOrder, void*(root));
    pthread_create(&thread[1],&attr, mergeBSTImplRevInOrder, void*(root));

}

 void mergeBSTImplInOrder(void *root)
    {
        root=(node*) root;
        if(!root) return;

        mergeBSTImpl(root->left);

        tempInorder=root->data

            /*This is where there has to be conditional checks such that execution would stop right here so I can compare varables **tempInorder** **tempRevInorder** with the variable "requiredSUM"*/

        mergeBSTImpl(root->right);
    }


 void mergeBSTImplRevInOrder(void *root)
    {
        root=(node*) root;
        if(!root) return;
        mergeBSTImpl(root->right);

        tempRevInorder=root->data;
        //A similar situation as the other function.

        mergeBSTImpl(root->left);
    }

那么......我试图在逻辑上做什么? 这是我在stackoverflow中的第一篇文章。我希望我能得到正确的格式和东西。如果没有,请善待。 =)

堆栈方法至少需要 O(logm + logn)空间。线程方式实际上可以通过更简单的代码和O(1)空间

来完成

以防万一,我想要完成的是:

  

2个函数,每个函数运行它自己的线程:
   Fn1 (比如说):一个是以Inorder方式递归的功能    Fn2 (比如说):两个,以反向顺序递归的函数。

     

每当任一函数从BST读取数据时,它都会存储   它们在静态变量中,并且必须检查从2个函数中保存的两个元素是否是   有比较。一个来自自己,另一个来自另一个功能。   如果还有2个元素,那么它找到了它的总和   具有requiredSUM的元素。如果变量的总和更大,它会让另一个函数继续运行直到它变为   下一个(这将是第二个最小的元素)。此函数保持不变,直到另一个函数获得新函数   元件。比较发生。如果此时,总和小于requiredSUM,则此函数继续执行,其他函数等待此函数获取下一个元素(第二个最小元素)。比较发生,这一直持续到找到所需目标总和的2个元素。

这是一种查找排序数组中所有整数对的算法,该数组总和为指定值。除了而不是排序数组,我们现在有一个BST 。只是为了表明,我将通过以下方式解决问题的数组版本:

#include <iostream>
#include <algorithm>

using namespace std;

void print_pairs(int * ptr, int num, int sum) 
{
    std::sort(ptr, ptr + num);
    int first = 0;
    int last = num - 1;

    while (first < last) 
    {
        int s = ptr[first] + ptr[last];
        if (s == sum) 
        {
            //cout<<ptr[first]<<“ “<< ptr[last]<<endl;
            ++first;
            --last;
        }
        else 
        {
            if (s < sum) 
                ++first; 
            else 
                --last;
        }
    }
}

int main() 
{
int test[] = {9, 3, 6, 5, 7, -1, 13, 14, -2, 12, 0};
print_pairs(test, sizeof(test) / sizeof(int), 12);
return 0;
}

1 个答案:

答案 0 :(得分:2)

我的感觉是线程不是你问题的答案。两个 cursor 状态或 iterator-like 对象保持向前和向后遍历的状态将给你相同的结果。

线程是一种协调执行的方式,而不是一种分离代码的方式。在任何情况下,你应该尽可能地避免线程,这是一种情况(线程永远不会同时运行)线程没有为解决方案增加价值

如果你坚持,那么你想要的是条件变量。

条件是一个线程将阻塞的位置,直到其他线程发出信号继续。条件与互斥锁相关联。

所以在thread1上你会:

thread1stopped=false; // let this start running
while (true) {
    pthread_mutex_lock(&mutex2); // lock on the other thread mutex
    while(!thread2stopped) {
        pthread_cond_wait(&cond2, &mutex2); // wait for the signal
    }
    pthread_mutex_unlock(&mutex2); // unlock the other thread mutex

    // Now we're running:
    // ... do whatever I need to do
    // ... until I need to stop.
    pthread_mutex_lock(&mutex1); // lock my mutex
    thread1stopped=true;         // change the state
    pthread_cond_signal(&cond1); // signal to the other thread
    pthread_mutex_unlock(&mutex1); // unlock my mutex
    pthread_mutex_lock(&mutex1); // lock my mutex
    thread1stopped=false;
    pthread_mutex_unlock(&mutex1); // unlock my mutex
 }

而另一个可以

thread2stopped=true; // let this start stopped
while (true) {
    pthread_mutex_lock(&mutex1); // lock on the other thread mutex
    while(!thread1stopped) {
        pthread_cond_wait(&cond1, &mutex1); // wait for the signal
    }
    pthread_mutex_unlock(&mutex1); // unlock the other thread mutex

    // Now we're running:
    // ... do whatever I need to do
    // ... until I need to stop.
    pthread_mutex_lock(&mutex2); // lock my mutex
    thread2stopped=true;         // change the state
    pthread_cond_signal(&cond2); // signal to the other thread
    pthread_mutex_unlock(&mutex2); // unlock my mutex
    pthread_mutex_lock(&mutex2); // lock my mutex
    thread2stopped=false;
    pthread_mutex_unlock(&mutex2); // unlock my mutex
 }

这有效:

  Thread1             Thread2
      .                   .
   --------           --------
   | exec |           | lock1| thread1stopped==false
   |      |           | wait | (wait unlocks)
   --------           |      |
      .               |      |
   --------           |      |
   |lock1 |           |      |
   |true  |           |      |
   |signal|---------->|unlock|
   --------           --------
      .                   .
   --------           --------
   | lock2|           | exec |
   | wait |           |      |
   |      |           --------
   |      |               .
   |      |           --------
   |      |           |lock2 |
   |      |           |true  |
   |unlock|<----------|signal|
   --------           --------

没有真正尝试过此代码,因此可能存在问题,死锁,竞争条件......但我希望它会给你一个起点。