快速排序和冒泡排序会产生不同的结果

时间:2016-03-04 19:00:46

标签: c arrays sorting quicksort missing-data


我面临一个单一的问题:
我有一张大桌子,内容很多都是一对。我必须按降序对它们进行排序。我写了一个BubbleSort程序并且工作正常,但是很难完成它的工作。所以我使用了一个QuickSort程序并且......排序之后数组内部的数据发生了变化! 所以我尝试了一个样本表,具有相似的尺寸和“易于写入”的内容,基本上是一个分配给

的cicle
    table[i][0]=i*3 

    table[i][1]=i*5 

和...工作正常。

使用的代码如下:

typedef struct MATCHES {
    short size;
    unsigned short values[10000][2];
} MATCHES;



int partition(MATCHES **data, int left, int right, int pivot, int col){
        int temp;
        int i;
        int storeIndex = left;
        int pivotVal = (**data).values[pivot][col];
        (**data).values[pivot][col] = (**data).values[right][col];
        (**data).values[right][col] = pivotVal;

        for(i = left; i < right; i++){
            if ((**data).values[i][col] >= pivotVal){ //Change this to greater then and BOOM we're done
                temp = (**data).values[i][col];
                (**data).values[i][col] = (**data).values[storeIndex][col];
                (**data).values[storeIndex][col] = temp;
                storeIndex++;
            }
        }
        temp = (**data).values[storeIndex][col];
        (**data).values[storeIndex][col] = (**data).values[right][col];
        (**data).values[right][col] = temp;
        return storeIndex;
    }

void quickSort(MATCHES **vec, int left, int right, int col) {
    int r;
      if (right > left) {
        r = partition(vec, left, right, right+1/2, col);
        quickSort(vec, left, r - 1, col);
        quickSort(vec, r + 1, right, col);
      }
    }

void sorter(MATCHES *table) {
    quickSort(&table, 0, (*table).size-1, 0);
    quickSort(&table, 0, (*table).size-1, 1);
}


int main () {
    MATCHES table;
    table.size=10000;
    int i;
    for (i=0; i<table.size; i++) {
        table.values[i][0]=i*3;
        table.values[i][1]=i*5;
    }
    printf("Unsorted\n");
    for (i=0; i<table.size; i++)
        printf("%d %d\n",table.values[i][0],table.values[i][1]);
    sorter(&table);
    printf("Sorted\n");
    for (i=0; i<table.size; i++)
        printf("%d %d\n",table.values[i][0],table.values[i][1]);
    return 0;
}

为了做另一次尝试,我把我需要的数据分类到这个程序中,结果又错了。

我将链接代码,因为初始化向量很长。

http://pastebin.com/Ztwu6iUP

提前感谢您的帮助!

编辑: 我找到了部分解决方案。我没有使用不稳定的quickSort,而是使用了mergeSort。现在,当我第二次对表格进行排序时,对于第二列的每个副本(或相同值的三倍),在第一列中我按升序排序数据。 代码如下:

void merge(MATCHES *v, int i1, int i2, int fine, int col, MATCHES *vout) {
    int i=i1, j=i2, k=i1;
    while (i<=i2-1 &&  j<=fine) {
        if ((*v).values[i][col]>(*v).values[j][col]) {
            (*vout).values[k][0]=(*v).values[i][0];
            (*vout).values[k][1]=(*v).values[i][1];
            i++;
        }
        else {
            (*vout).values[k][0]=(*v).values[j][0];
            (*vout).values[k][1]=(*v).values[j][1];
            j++;
        }
        k++;
    }
    while (i<=i2-1){
        (*vout).values[k][0]=(*v).values[i][0];
        (*vout).values[k][1]=(*v).values[i][1];
        i++;
        k++;
    }
    while (j<=fine){
        (*vout).values[k][0]=(*v).values[j][0];
        (*vout).values[k][1]=(*v).values[j][1];
        j++;
        k++;
    }
    for (i=i1; i<=fine; i++) {
        (*v).values[i][0]=(*vout).values[i][0];
        (*v).values[i][1]=(*vout).values[i][1];
    }
}

void mergeSort(MATCHES *v, int iniz, int fine, int col, MATCHES *vout) {
    int mid;
    if(iniz<fine){
        mid=(fine+iniz)/2;
        mergeSort(v, iniz, mid, col, vout);
        mergeSort(v, mid+1, fine, col, vout);
        merge(v, iniz, mid+1, fine, col, vout);
    }
}

有任何提示吗?

1 个答案:

答案 0 :(得分:1)

为了使用quicksort获得稳定性,您需要回答以下问题。

Can I tell the difference between a1 and a2?

如果a1和a2因为有辅助字段而不同,那么就会有一个快速排序的“稳定”解决方案。

如果a1和a2不同,因为它们是在不同的时间添加的(一个无关紧要的字段),那么排序是不稳定的,有时在a2之前有时会有a1,有时甚至之后。

在您的问题中,尚不清楚这些数字是否已链接

1,9
5,8
3,7
4,6

应该去: -

1,6
3,7
4,8
5,9

4,6
3,7
5,8
1,9

有两种独立的排序吗?或者它是次要字段排序。

合并代码看起来像是辅助字段排序。

在辅助字段

上排序

要对辅助字段进行排序,比较需要如下: -

int compare( Atype* lhs, Atype * rhs )
{
  if( lhs->field1 < rhs->field1 ) return -1;
  if( lhs->field1 > rhs->field1 ) return  1;

  if( lhs->field2 < rhs->field2 ) return -1;
  if( lhs->field2 > rhs->field2 ) return  1;

  /* more fields can be added here */
    return 0;
}

而不是独立地对列进行排序

  quickSort(&table, 0, (*table).size-1, 0);
  quickSort(&table, 0, (*table).size-1, 1);

尝试以下方法。       将分类合二为一: -

  quickSort(&table, 0, (*table).size-1 );

更改比较以采用基本数组

 int compare( short * lhs, short * rhs ) /* sort by 1 then 0 */
 {
  if( lhs[1] < rhs[1] ) return -1;
  if( lhs[1] > rhs[1] ) return  1;


  if( lhs[0] < rhs[0] ) return -1;
  if( lhs[0] > rhs[0] ) return  1;
  return 0;

 }     

分区变为

int partition(MATCHES **data, int left, int right, int pivot, int col){
    int temp;
    int i;
    int storeIndex = left;
    short pivotVal[2];
    pivotVal[0] = (**data).values[pivot][0];
    pivotVal[1] = (**data).values[pivot][1];
     /* here you were jumbling pivot value - not keeping [0,1] together */
    (**data).values[pivot][0] = (**data).values[right][0];
    (**data).values[pivot][1] = (**data).values[right][1];
    (**data).values[right][0] = pivotVal[0];
    (**data).values[right][1] = pivotVal[1];

    for(i = left; i < right; i++){
        if ( compare( (**data).values[i] , pivotVal ) >= 0){ //Change this to greater then and BOOM we're done
            temp = (**data).values[i][0];
            (**data).values[i][0] = (**data).values[storeIndex][0];
            (**data).values[storeIndex][0] = temp;

            temp = (**data).values[i][1];
            (**data).values[i][1] = (**data).values[storeIndex][1];
            (**data).values[storeIndex][1] = temp;

            storeIndex++;
        }
    }
    temp = (**data).values[storeIndex][0];
    (**data).values[storeIndex][0] = (**data).values[right][0];
    (**data).values[right][0] = temp;

    temp = (**data).values[storeIndex][1];
    (**data).values[storeIndex][1] = (**data).values[right][1];
    (**data).values[right][1] = temp;

    return storeIndex;
}