合并姓氏排序结构,给出细分错误

时间:2019-04-15 05:36:43

标签: c++ arrays sorting struct

我试图按姓氏对结构体数组进行排序,如果姓氏相同,则按名字排序。

struct Person {
    std::string kNum;
    std::string last;
    std::string first;
    int zipCode;
};

这些是合并排序的功能。

void nameSort(Person* array, int size) {
    int high = size - 1;
    mergeSort(array, 0, high);
}
void mergeSort(Person* arr, int low, int high) {
    if (low < high) {
        int mid = low + (high - 1) / 2;

        mergeSort(arr, low, mid);
        mergeSort(arr, mid + 1, high);

        merge(arr, low, mid, high);
    }
}
void merge(Person* arr, int low, int mid, int high) {
    Person *temp = new Person[high - low + 1];
    int i = low;
    int j = mid + 1;
    int k =0;

    while (i <= mid && j <= high) {
        if (arr[i].last != arr[j].last) {
            if (arr[i].last <= arr[j].last) {
                temp[k++] = arr[j++];
            } else {
                temp[k++] = arr[i++];
            }
        } else {
            if (arr[i].first <= arr[j].last) {
                temp[k++] = arr[j++];
            } else {
                temp[k++] = arr[i++];
            }
        }
    }

    while (i < mid) {
        temp[k++] = arr[i++];
    }
    while(j <= high) {
        temp[k++] = arr[j++];
    }

    for (int x = low; x < high; ++x) {
        arr[x] = temp[x];
    }


    delete [] temp;
}

在控制台上只是退出。我在DrMemory上运行它,给我一个分段错误。我试图寻找超出范围但找不到的地方。

1 个答案:

答案 0 :(得分:0)

拥有

int mid = (low + high) / 2;

您首先遇到有关 mid 的问题,例如,如果 low 为2而 high 为3,则 mid 值3,然后递归调用 mergeSort ,其中 low 为2,而 high 为3递归直到堆栈爆炸。

可见,其名称表示 mid 必须是 low high 之间的中间索引,所以

 while (i < mid) {
   temp[k++] = arr[i++];
 }

其他问题在合并

while (i <= mid) {
    temp[k++] = arr[i++];
}

您错过元素等级 mid ,必须为

for (int x = low; x < high; ++x) {
    arr[x] = temp[x];
}

for (i = low, k = 0; i <= high; ++i, ++k)
  arr[i] = temp[k];

您假设 arr temps 的大小相同,并且它们的索引对应,但这是错误的, temp arr ,必须是

#include <string>
#include <iostream>

struct Person {
    std::string kNum;
    std::string last;
    std::string first;
    int zipCode;
};

void merge(Person* arr, int low, int mid, int high) {
    Person *temp = new Person[high - low + 1];
    int i = low;
    int j = mid + 1;
    int k =0;

    while (i <= mid && j <= high) {
        if (arr[i].last != arr[j].last) {
            if (arr[i].last <= arr[j].last) {
                temp[k++] = arr[j++];
            } else {
                temp[k++] = arr[i++];
            }
        } else {
            if (arr[i].first <= arr[j].last) {
                temp[k++] = arr[j++];
            } else {
                temp[k++] = arr[i++];
            }
        }
    }

    while (i <= mid) {
        temp[k++] = arr[i++];
    }
    while(j <= high) {
        temp[k++] = arr[j++];
    }

    for (i = low, k = 0; i <= high; ++i, ++k)
      arr[i] = temp[k];


    delete [] temp;
}

void mergeSort(Person* arr, int low, int high) {
    if (low < high) {
        int mid = (low + high) / 2; // mid

        mergeSort(arr, low, mid);
        mergeSort(arr, mid + 1, high);

        merge(arr, low, mid, high);
    }
}

void nameSort(Person* array, int size) {
    int high = size - 1;
    mergeSort(array, 0, high);
}

int main()
{
  Person a[] = {
    { "K1000001","Thompson","Loyal",97894 },
    { "K1000002","Abbott","Ward",97095 },
    { "K1000003","Hauck","Mario",97587 },
    { "K1000004","Mertz","Bret",97070 },
    { "K1000005","Jacobs","Hubert",97364 },
    { "K1000006","Rolfson","Dixie",97335 },
    { "K1000007","Weber","Yoshiko",97091 },
    { "K1000008","Beier","Jessika",97858 },
    { "K1000009","White","Sophie",97719 },
    { "K1000010","Dibbert","Jordyn",97607 },
    { "K1000011","Schultz","Markus",97515 },
    { "K1000012","Kemmer","Bonnie",97264 },
    { "K1000013","Klein","Llewellyn",97699 },
    { "K1000014","Barton","Callie",97276 },
    { "K1000015","Bartell","Erich",97884 },
    { "K1000016","Marks","Annabel",97493 },
    { "K1000017","Hirthe","Mekhi",97487 },
    { "K1000018","Gleichner","Zita",97073 },
  };
  const int sz = sizeof(a)/sizeof(a[0]);

  for (int i = 0; i != sz; ++i)
    std::cout << a[i].last << ' ' << a[i].first << ' ' << a[i].kNum << ' ' << a[i].zipCode << std::endl;

  std::cout << "---------" << std::endl;

  nameSort(a, sz);

  for (int i = 0; i != sz; ++i)
    std::cout << a[i].last << ' ' << a[i].first << ' ' << a[i].kNum << ' ' << a[i].zipCode << std::endl;
}

这些更改之后,您的程序将元素排序得很好


pi@raspberrypi:/tmp $ g++ -g -pedantic -Wextra -Wall s.cc
pi@raspberrypi:/tmp $ ./a.out
Thompson Loyal K1000001 97894
Abbott Ward K1000002 97095
Hauck Mario K1000003 97587
Mertz Bret K1000004 97070
Jacobs Hubert K1000005 97364
Rolfson Dixie K1000006 97335
Weber Yoshiko K1000007 97091
Beier Jessika K1000008 97858
White Sophie K1000009 97719
Dibbert Jordyn K1000010 97607
Schultz Markus K1000011 97515
Kemmer Bonnie K1000012 97264
Klein Llewellyn K1000013 97699
Barton Callie K1000014 97276
Bartell Erich K1000015 97884
Marks Annabel K1000016 97493
Hirthe Mekhi K1000017 97487
Gleichner Zita K1000018 97073
---------
White Sophie K1000009 97719
Weber Yoshiko K1000007 97091
Thompson Loyal K1000001 97894
Schultz Markus K1000011 97515
Rolfson Dixie K1000006 97335
Mertz Bret K1000004 97070
Marks Annabel K1000016 97493
Klein Llewellyn K1000013 97699
Kemmer Bonnie K1000012 97264
Jacobs Hubert K1000005 97364
Hirthe Mekhi K1000017 97487
Hauck Mario K1000003 97587
Gleichner Zita K1000018 97073
Dibbert Jordyn K1000010 97607
Beier Jessika K1000008 97858
Barton Callie K1000014 97276
Bartell Erich K1000015 97884
Abbott Ward K1000002 97095

编译和执行:

{{1}}