You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.2 KiB
127 lines
3.2 KiB
/*
|
|
* Copyright(C) 1999-2020 National Technology & Engineering Solutions
|
|
* of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
|
|
* NTESS, the U.S. Government retains certain rights in this software.
|
|
*
|
|
* See packages/seacas/LICENSE for details
|
|
*/
|
|
|
|
#include "defs.h"
|
|
#include <stdio.h>
|
|
|
|
static void recursesort(double *vals, int nvals, int *indices, int *space);
|
|
static void merge(double *vals, int *indices, int length1, int length2, int *space);
|
|
|
|
void ch_mergesort(double *vals, int nvals, int *indices, int *space)
|
|
/* Merge sort values in vals, returning sorted indices. */
|
|
/* values to be sorted */
|
|
/* number of values */
|
|
/* indices of sorted list */
|
|
/* space for nvals integers */
|
|
{
|
|
extern int DEBUG_BPMATCH; /* debugging flag for bipartite matching */
|
|
int flag; /* has sorting screwed up? */
|
|
int i;
|
|
|
|
for (i = 0; i < nvals; i++) {
|
|
indices[i] = i;
|
|
}
|
|
|
|
recursesort(vals, nvals, indices, space);
|
|
|
|
if (DEBUG_BPMATCH > 0) {
|
|
flag = FALSE;
|
|
for (i = 1; i < nvals; i++) {
|
|
if (vals[indices[i - 1]] > vals[indices[i]]) {
|
|
flag = TRUE;
|
|
}
|
|
}
|
|
if (flag) {
|
|
printf("List improperly sorted in mergesort\n");
|
|
if (DEBUG_BPMATCH > 1) {
|
|
for (i = 1; i < nvals; i++) {
|
|
printf("%d %f\n", indices[i], vals[indices[i]]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void recursesort(double *vals, int nvals, int *indices, int *space)
|
|
/* Recursive implementation of mergesort. */
|
|
/* values to be sorted */
|
|
/* number of values */
|
|
/* indices of sorted list */
|
|
/* space for nvals integers */
|
|
{
|
|
int length1, length2; /* lengths of two sublists */
|
|
int i; /* temporary value */
|
|
|
|
/* First consider base cases */
|
|
if (nvals <= 1) {
|
|
return;
|
|
}
|
|
if (nvals == 2) {
|
|
if (vals[indices[0]] <= vals[indices[1]]) {
|
|
return;
|
|
}
|
|
i = indices[0];
|
|
indices[0] = indices[1];
|
|
indices[1] = i;
|
|
return;
|
|
}
|
|
|
|
else {
|
|
length1 = nvals / 2;
|
|
length2 = nvals - length1;
|
|
recursesort(vals, length1, indices, space);
|
|
recursesort(vals, length2, indices + length1, space);
|
|
merge(vals, indices, length1, length2, space);
|
|
}
|
|
}
|
|
|
|
static void merge(double *vals, int *indices, int length1, int length2, int *space)
|
|
/* Merge two sorted lists to create longer sorted list. */
|
|
/* values to be sorted */
|
|
/* start of first sorted list */
|
|
/* number of values in first list */
|
|
/* number of values in second list */
|
|
/* sorted answer */
|
|
{
|
|
int n1, n2; /* number of values seen in each list */
|
|
int *spaceptr; /* loops through space array */
|
|
int *index1, *index2; /* pointers into two lists */
|
|
|
|
n1 = n2 = 0;
|
|
spaceptr = space;
|
|
index1 = indices;
|
|
index2 = indices + length1;
|
|
|
|
while (n1 < length1 && n2 < length2) {
|
|
if (vals[*index1] <= vals[*index2]) {
|
|
*spaceptr++ = *index1++;
|
|
++n1;
|
|
}
|
|
else {
|
|
*spaceptr++ = *index2++;
|
|
++n2;
|
|
}
|
|
}
|
|
|
|
/* Now add on remaining elements */
|
|
while (n1 < length1) {
|
|
*spaceptr++ = *index1++;
|
|
++n1;
|
|
}
|
|
|
|
while (n2 < length2) {
|
|
*spaceptr++ = *index2++;
|
|
++n2;
|
|
}
|
|
|
|
spaceptr = space;
|
|
index1 = indices;
|
|
for (n1 = length1 + length2; n1; n1--) {
|
|
*index1++ = *spaceptr++;
|
|
}
|
|
}
|
|
|