我如何通过合并排序将数组拆分为3部分?

时间:2017-07-22 18:29:00

标签: arrays sorting

我写这个算法usudo代码将我的数组溢出到3部分 想检查一下这个算法的有效性吗? 有什么错误吗?

.container-fluid {
  padding-left: 0px;
  padding-right: 0px;
}

@media only screen and (min-width : 481px) {
  .flex-row.row {
    display: flex;
    flex-wrap: wrap;
  }
  .flex-row.row > [class*='col-'] {
    display: flex;
    flex-direction: column;
  }
  .flex-row.row:after,
  .flex-row.row:before {
    display: flex;
  }
  .flex-row.row > [class*='col-'] > .box {
    display: flex;
    flex: 1;
  }
}

#sidebar {
  background: #B3D6B3;
  border: solid 10px #D6E9D6;
  margin: 0;
}

#main {
  background: pink;
  border: solid 10px #D6E9D6;
  border-left: 0px;
  margin: 0;
}

1 个答案:

答案 0 :(得分:0)

考虑这种情况:Start = 2,Stop = 4.代码设置New_Stop = 2,这是正常的,但它设置MULTI = 4,这是错误的(它应该是3)。长度需要基于Stop-Start,而不是Array.Length。最后一次调用应该是MergeSort(...,MULTI + 1,Stop)

由于没有活动已经过了2天,如果有人感兴趣,示例C ++代码使用结束索引而不是最后一个索引。可以通过使用SplitMerge()的两个相互递归实例来消除Merge()中的复制循环,其中一个排序数据最终在[]中,另一个在b []中,以便交替合并的方向取决于在递归的水平上,但这只会加大我系统上1600万个整数的排序约8.5%。

通常情况下,如果k方式合并排序与k> 2,使用自下而上的合并排序,但在这种情况下,问题意味着要使用3向自上而下的合并排序。

void SplitMerge(int a[], int b[], int bb, int ee);
void Merge(int a[], int b[], int bb, int m1, int m2, int ee);

// bb is beginning index, ee is ending index    
void MergeSort(int a[], int bb, int ee)
{
    if((ee - bb) < 2)           // if < 2 elements
        return;
    if((ee - bb) == 2){         // if 2 elements
        ee--;                   //  ee = last index
        if(a[bb] > a[ee])       //  swap if needed
            std::swap(a[bb], a[ee]);
        return;
    }
    int *b = new int [ee-bb];  // allocate temp array
    SplitMerge(a, b, bb, ee);  // top down merge sort
    delete[] b;                // delete temp array
}

// b[] is temp array
// bb is beginning index, ee is ending index    
void SplitMerge(int a[], int b[], int bb, int ee)
{
    if((ee - bb) == 1)          // if 1 element, return
        return;
    if((ee - bb) == 2){         // if 2 elements
        ee--;                   //  ee = last index
        if(a[bb] > a[ee])       //  swap if needed
            std::swap(a[bb], a[ee]);
        return;
    }
    int sz = ((ee+1-bb)/3);     // split into 3 parts
    int m1 = bb + sz;
    int m2 = bb + sz + sz;
    SplitMerge(a, b, bb, m1);    // merge sort 1st part
    SplitMerge(a, b, m1, m2);    // merge sort 2nd part
    SplitMerge(a, b, m2, ee);    // merge sort 3rd part
    Merge(a, b, bb, m1, m2, ee); // merge the 3 parts
}

// b[] is temp array
// bb is beginning index == beg of run 0
// m1 is start of run 1  == end of run 0
// m2 is start of run 2  == end of run 1
// ee is ending index    == end of run 2
void Merge(int a[], int b[], int bb, int m1, int m2, int ee)
{
int i0 = bb;
int i1 = m1;
int i2 = m2;
int ia = bb;

    // copy a to b
    for(int i = bb; i < ee; i++)
        b[i] = a[i];

    while(1){                           // merge run 0, 1, 2
        if(b[i0] <= b[i1] && b[i0] <= b[i2]){  // if run0[] smallest
            a[ia++] = b[i0++];
            if(i0 < m1)                 // if not end of run 0
                continue;               //   continue back to while
            i0 = i1;                    // merge runs 1 and 2
            i1 = i2;
            m1 = m2;
            m2 = ee;
            break;
        }
        if(b[i1] <= b[i2]){             // if run1[] smallest
            a[ia++] = b[i1++];
            if(i1 < m2)                 // if not end of run 1
                continue;               //   continue back to while
            i1 = i2;                    // merge runs 0 and 2
            m2 = ee;
            break;
        } else {                        // else run2[] smallest
            a[ia++] = b[i2++];
            if(i2 < ee)                 // if not end of run 2
                continue;               //   continue back to while
            break;                      // merge runs 0 and 1
        }
    }

    while(1){                           // merge runs "0" and "1"
        if(b[i0] <= b[i1]){             // if run0[] smallest
            a[ia++] = b[i0++];
            if(i0 < m1)                 // if not end of run 0
                continue;               //   continue back to while
            i0 = i1;                    // copy rest of run 1
            m1 = m2;
            break;
        } else {                        // else run1[] smallest
            a[ia++] = b[i1++];
            if(i1 < m2)                 // if not end of run 1
                continue;               //   continue back to while
            break;                      // copy rest of run 0
        }
    }

    do                                  // copy rest of run "0"
        a[ia++] = b[i0++];
    while(i0 < m1);
}