C++ 带对象类的合并排序算法
在过去的几个小时里,我一直想弄明白这件事,但没有成功 我有几个用于添加数据的类,因此我可以显示它们,但现在我必须实现一个MergeSort算法,根据标题对这些数据进行排序 我有对象CD,所有其他类都从它继承,对象CD有属性title,type char 现在,当我将指针传递到我的类时,我会进行比较和检查,但它没有按应有的方式工作: 这是我的排序算法函数:C++ 带对象类的合并排序算法,c++,sorting,mergesort,C++,Sorting,Mergesort,在过去的几个小时里,我一直想弄明白这件事,但没有成功 我有几个用于添加数据的类,因此我可以显示它们,但现在我必须实现一个MergeSort算法,根据标题对这些数据进行排序 我有对象CD,所有其他类都从它继承,对象CD有属性title,type char 现在,当我将指针传递到我的类时,我会进行比较和检查,但它没有按应有的方式工作: 这是我的排序算法函数: void merge(CD *a[], int, int, int); void merge_sort(CD *a[], int low,
void merge(CD *a[], int, int, int);
void merge_sort(CD *a[], int low, int high) {
int mid;
if (low < high) {
mid = (low + high) / 2;
merge_sort(a, low, mid);
merge_sort(a,mid + 1, high);
merge(a, low, mid, high);
}
}
void merge(CD *a[], int low, int mid, int high) {
int h, i, j, k;
CD *b;
h = low;
i = low;
j = mid + 1;
while ((h <= mid) && (j <= high)) {
if (a[h]->title[100] <= a[j]->title[100]) {
b[i].title[100] = a[h]->title[100];
h++;
}
else {
b[i].title[100] = a[j]->title[100];
j++;
}
i++;
}
if (h > mid) {
for (k = j; k <= high; k++) {
b[i].title[100] = a[k]->title[100];
i++;
}
}
else {
for (k = h; k <= mid; k++) {
b[i].title[100] = a[k]->title[100];
i++;
}
}
for (k = low; k <= high; k++)
a[k]->title[100] = b[k].title[100];
}
void合并(CD*a[],int,int,int);
无效合并排序(CD*a[],整数低位,整数高位){
int mid;
如果(低<高){
中等=(低+高)/2;
合并排序(a、低、中);
合并排序(a、中+1、高);
合并(a、低、中、高);
}
}
无效合并(CD*a[],整数低,整数中,整数高){
inth,i,j,k;
CD*b;
h=低;
i=低;
j=mid+1;
而((h)标题[100];
h++;
}
否则{
b[i].标题[100]=a[j]>标题[100];
j++;
}
i++;
}
如果(h>mid){
对于(k=j;k标题[100];
i++;
}
}
否则{
对于(k=h;k标题[100];
i++;
}
}
对于(k=low;k title[100]=b[k]。title[100];
}
你知道如何实现这样的功能吗?首先,更新你的问题,以显示你在
合并
、合并排序
和光盘
中的真实代码。我将参考评论中发布的实际代码
您的问题可能源于您对标题进行排序,而不是根据标题进行排序。在代码中,您将CD标题分配给另一张CD的任何地方都会出错。您比较了标题,但重新定位和排序了对象本身(或者在您的情况下,指向对象本身的指针)
无论如何,要解决此问题,只需替换如下代码:
x->title = y->title;
为此:
x = y;
例如,代替
b[i]->title = a[h]->title;
你应该写信的
b[i] = a[h];
顺便说一句,内存分配和释放并不是你事后才想到的事情,看看它是否有效!即使是平庸的程序员也会小心对待内存;优秀的程序员会以赤裸裸的爱和尊重对待内存。我会在程序注释中指出,你发布的代码中有几个错误。因为你没有这样做如果我不给我们定义
Popular
、Symphony
和Opera
,我会有自己的定义。为了方便起见,我把所有代码都放在一个文件中
#pragma once
#include <string>
#include <iostream>
using namespace std;
class CD {
public:
string publisher, title, location, year, empty;
public:
CD()
{
publisher = "";
title = "";
location = "";
year = "";
empty = "";
}
void virtual input() = 0;
void virtual output() = 0;
};
class Popular : public CD
{
public:
Popular(const string& name)
{
title = name;
}
virtual void input()
{
return;
}
virtual void output()
{
return;
}
};
void merge(CD *a[], int, int, int);
void merge_sort(CD *a[], int low, int high) {
int mid;
if (low < high) {
mid = low + (high - low) / 2; //avoid overflow
merge_sort(a, low, mid);
merge_sort(a, mid + 1, high);
merge(a, low, mid, high);
}
}
void merge(CD *a[], int low, int mid, int high) {
int p1 = low;
int p2 = mid + 1;
CD ** merged = (CD**)malloc(sizeof(CD*) * (high - low + 1)); // CD *b[high] isn't illegal c++ syntax, VLA is part of C99.
int p = 0;
while(p1 < mid + 1 && p2 < high + 1)
{
if(a[p1]->title > a[p2]->title)
{
merged[p] = a[p2];
p2++;
}
else
{
merged[p] = a[p1];
p1++;
}
p++;
}
while(p1 < mid + 1)
{
merged[p++] = a[p1++];
}
while(p2 < high + 1)
merged[p++] = a[p2++];
for(int i = 0;i < (high - low + 1); i++)
{
a[low + i] = merged[i];
}
free(merged);
}
int main() {
CD *cdptr[100]; //pointer declaration for each of our class
int n = 0, choose;
// just to test the mergesort
CD* c1 = new Popular("hello");
CD* c2 = new Popular("world");
CD* c3 = new Popular("coldplay");
CD* c4 = new Popular("pink");
cdptr[n++] = c1;
cdptr[n++] = c2;
cdptr[n++] = c3;
cdptr[n++] = c4;
char terminate = 'n'; // you should initialize this variable.
do // do-while statement which allows the user to enter data and terminate the program when he wants
{
cout << "\n1.Classical";
cout << "\n2.Popular";
cout << "\n3.Sort";
cout << "\n4.Display";
cout << "\n5.Terminate program";
cout << endl << endl;
cout << "\nChoose category: ";
cin >> choose;
switch (choose) //switch for the user to choose the type of input
{
//skip the case 1, 2
case 3:
merge_sort(cdptr, 0, n - 1); // element indices begin at 0.
break;
case 4:
if (n == 0)
cout << "\nNo data entered!" << endl;
for (int i = 0; i < n; i++) {
cdptr[i]->output();
cout << endl;
}
break;
case 5:
cout << "\nDo you want to terminate the program? (y/n)";
cin >> terminate;
break;
default:
cout << "\nNot recognized value!" << endl;
}
} while (terminate != 'y');
for(int i = 0; i < 4; ++i)
cout<<cdptr[i]->title<<endl;
delete c1;
delete c2;
delete c3;
delete c4;
return 0;
}
title[100]?您能告诉我们对象CD的定义吗?这里:class CD{public:string publisher,location,year,empty;CD();void virtual input()=0;void virtual output()=0;char title[100];};您不能像
那样访问成员变量。title[100]
,title[100]
表示数组的第101个标题
,超出了范围。嗯,我想我对它做了一点修改,我使用了字符串类型作为变量。对我来说不起作用的是,我无法访问值,无法与值进行比较,也无法将值分配给其他对象。知道如何解决这个问题吗?不知道她的巨大问题是,你在没有分配任何内存的情况下,把东西写到“b”中。如果是这样,你就是在写“排序的”数据消失在稀薄的空气中;不仅它消失了,你再也找不到它,而且它还覆盖了地址空间中的一些随机内容。我很惊讶你的代码没有在每次运行时崩溃(特别是在调试模式/禁用优化的情况下)嗨,谢谢你花时间,试图回答我,事情是我没有编程C++在很长一段时间,我不记得任何东西,现在我正在尝试做一些事情,但没有任何成功…所以我已经更新了你说的东西,但程序仍然退出代码错误137,有任何想法?我将非常感激:)
1.Classical
2.Popular
3.Sort
4.Display
5.Terminate program
Choose category: 3
1.Classical
2.Popular
3.Sort
4.Display
5.Terminate program
Choose category: 5
Do you want to terminate the program? (y/n)y
coldplay
hello
pink
world