这是线程问题吗?如果是这样,我该如何解决?

时间:2018-09-21 13:45:01

标签: c#

我正在一个项目中,该项目涉及同时运行的2种单独的排序算法。但是,当排序完成时,即使我同时运行相同的算法,也不会对两个数组进行排序。我认为这可能是线程内发生的错误,其中一种算法正在从另一种算法获取计算出的答案(但我不确定100%正确)。

仅运行一种算法就可以工作。

如果这是问题所在,您知道如何解决吗?

如果不是问题,那是什么,我该如何克服?

以下是发生错误的代码(算法保存在各自的类中):

        string algorithmLeft = "";
        string algorithmRight = "";

        if (cboxDropDownLeft.SelectedItem != null)
        {
            algorithmLeft = cboxDropDownLeft.SelectedItem.ToString();
        }
        if (cboxDropDownRight.SelectedItem != null)
        {
            algorithmRight = cboxDropDownRight.SelectedItem.ToString();
        }

        ThreadStart tsLeft = delegate ()
        {
            try
            {
                switch (algorithmLeft)
                {
                    case ("Bubble Sort"):
                        Bubble_Sort bubbleSort = new Bubble_Sort();
                        bubbleSort.sortArray();
                        break;

                    case ("Merge Sort"):
                        Merge_Sort mergeSort = new Merge_Sort();
                        mergeSort.sortArray();
                        break;

                    case ("Quick Sort"):
                        Quick_Sort quickSort = new Quick_Sort();
                        quickSort.sortArray();
                        break;
                }
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }

        };

        ThreadStart tsRight = delegate ()
        {
            try
            {
                switch (algorithmRight)
                {
                    case ("Bubble Sort"):
                        Bubble_Sort bubbleSort = new Bubble_Sort();
                        bubbleSort.sortArray();
                        break;

                    case ("Merge Sort"):
                        Merge_Sort mergeSort = new Merge_Sort();
                        mergeSort.sortArray();
                        break;

                    case ("Quick Sort"):
                        Quick_Sort quickSort = new Quick_Sort();
                        quickSort.sortArray();
                        break;

                }
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }

        };

        if (algorithmLeft != "")
        {
            Thread tLeft = new Thread(tsLeft);
            tLeft.Start();
        }
        if (algorithmRight != "")
        {
            Thread tRight = new Thread(tsRight);
            tRight.Start();
        }

气泡排序:

    public override void sortArray()
    {
        try
        {
            int n = arrayToSort.Count - 1;

            for (int loop1 = 0; loop1 < n; loop1++)
            {

                for (int loop2 = n; loop2 > loop1; loop2--)
                {
                    if (((IComparable)arrayToSort[loop2 - 1]).CompareTo(arrayToSort[loop2]) > 0)
                    {
                        object temp = arrayToSort[loop2];
                        arrayToSort[loop2] = arrayToSort[loop2 - 1];
                        arrayToSort[loop2 - 1] = temp;
                    }
                    Thread.Sleep(speed);
                }

            }
        }
        catch (Exception err)
        {
            MessageBox.Show(err.Message);
        }
    }

合并排序:

    public override void sortArray()
    {
        try
        {
            sort(arrayToSort, 0, arrayToSort.Count - 1);
        }
        catch (Exception err)
        {
            MessageBox.Show(err.Message);
        }

    }

        public void sort(ArrayList arrayToSort, int left, int right)
    {
        if (left < right)
        {
            int m = left + (right - left) / 2;

            sort(arrayToSort, left, m);
            sort(arrayToSort, m + 1, right);
            merge(arrayToSort, left, m, right);
        }
    }

    public void merge(ArrayList data, int left, int mid, int right)
    {
        int i, j, k;
        int n1 = mid - left + 1;
        int n2 = right - mid;
        ArrayList L = new ArrayList(n1);
        ArrayList R = new ArrayList(n2);

        for (i = 0; i < n1; i++)
        {
            L.Add(data[left + i]);
        }

        for (j = 0; j < n2; j++)
        {
            R.Add(data[mid + 1 + j]);
        }

        i = 0;
        j = 0;
        k = left;

        while (i < n1 && j < n2)
        {
            if (((IComparable)L[i]).CompareTo(R[j]) < 0)
            {
                data[k] = L[i];
                i++;
            }
            else
            {
                data[k] = R[j];
                j++;
            }
            k++;
        }

        while (i < n1)
        {
            data[k] = L[i];
            i++;
            k++;
            Thread.Sleep(speed);
        }

        while (j < n2)
        {
            data[k] = R[j];
            j++;
            k++;
            Thread.Sleep(speed);
        }
    }

快速排序:

    public int partition(ArrayList arrayToSort, int left, int right)
    {
        int pivot = (int)arrayToSort[left];

        while (true)
        {
            while (((IComparable)arrayToSort[left]).CompareTo(pivot) < 0)
            {
                left++;
            }

            while (((IComparable)arrayToSort[right]).CompareTo(pivot) > 0)
            {
                right--;
            }

            if (left < right)
            {
                object temp =arrayToSort[right];
                arrayToSort[right] = arrayToSort[left];
                arrayToSort[left] = temp;
                Thread.Sleep(speed);
            }
            else
            {
                return right;
            }
        }
    }

    public override void sortArray()
    {
        try
        {
            sort(arrayToSort, 0, arrayToSort.Count - 1);
        }
        catch (Exception err)
        {
            MessageBox.Show(err.Message);
        }
    }

    public void sort(ArrayList arr, int left, int right)
    {
        if (left < right)
        {
            int pivot = partition(arr, left, right);

            if (pivot > 1)
            {
                sort(arr, left, pivot - 1);
            }

            if (pivot + 1 < right)
            {
                sort(arr, pivot + 1, right);
            }
        }
    }

用于创建要排序的2个数组的算法:

        ArrayCreator arrayCreator = new ArrayCreator();
        arrayCreator.createArray(arrayLeft);
        arrayRight = arrayLeft;

ArrayCreator:

    public void createArray(ArrayList array)
    {
        for (int i = 0; i < 50; i++)
        {
            Random rnd = new Random();
            int x = rnd.Next(1, 400);
            array.Add(x);
            Thread.Sleep(15);
        }
    }

2 个答案:

答案 0 :(得分:0)

您已声明,如果单个线程正在运行其中一种算法,则排序工作正常,但是当您使用其他算法时,结果将不再正确。这意味着线程正在阻止彼此取得成功。

让我解释一下:假设您有两个线程,T1和T2。如果他们都在比较x和y,那么您有两种可能的情况

场景1

T1比较x和y并意识到它们需要交换 T1交换x和y T2 copmares x和y并意识到它们的顺序正确

结果:成功

场景2

T1比较x和y并意识到它们需要交换 T2比较x和y并意识到它们需要交换 T1交换x和y T2交换y和x

结果:失败,T2在T1进行比较之后但在T1进行交换之前进行比较。

因此,这是不安全的。最好让线程对自己的问题空间分区进行排序,然后对排序后的子集进行合并排序。

答案 1 :(得分:-1)

克隆arrayLeft解决了这个问题。

感谢所有帮助,非常感谢。