C++对象、对象数组的排序

来源:互联网 发布:网络机顶盒什么样的好 编辑:程序博客网 时间:2024/06/05 17:34

C++动态对象数组及其排序(一)


相信在学习完对象数组后,大家肯定回想起了数组当中的动态数据的申请以及需要排序的问题。同样的,类(class)中同样有着排序的问题,其内容大概都是 类似的:要求用户乱序输入N个类的对象信息,然后再按类的某个成员变量为索引(比如工号)顺序或倒序排序。

问题分析:
1、对象必须按用户输入的个数进行申请;
2、一系列对象数组的排序问题;

需要按用户输入的个数来申请相应个数个对象,这需要申请对象数组,而且还得是动态的。这就需要像申请动态数组一样申请数组对象。其中,建立的类的名字当成对象指针的数据类型,用new运算符开辟N个类类型的对象。例:


#include<iostream>using namespace std;class A{public:    int key;    char id[10];};void main(){int n;cin>>n;  //让用户统计需要开辟的对象个数,并输入这里的nA *p=new A[n];//创建n个A的对象}
这样就开辟了个对象,每个对象的名字分别是p[0]至p[n-1]。就像一般的对象名,可以通过点操作符对其中的内容进行访问:

p[i].key=10;

但是这里要注意,类的析构函数需要在程序结束、或显式调用时,才会把每个对象所占的空间析构。对于要求比较高的编程环境,这是非常致命的。由于new出的对象内存占用贯穿整个程序,会消耗大量计算机资源;然而这个动态对象很有可能只使用一次。所以要养成良好的习惯,在使用完动态数据后及时删除。
删除new出的空间使用delete标识符,然而仅仅写delete p;是不够的,结果只是删除了p[0]这一个对象,而剩下的n-1个对象仍会造成内存泄露。因此要这样写:

delete[] p;


到此为止我们就按要求申请了n个(n为输入值)动态对象数组。



接下来我们为这个类构建了输入输出的成员函数,用来更好地描述一系列对象数组排序的问题。把上面的类修改如下:
class A{public:    int key;    char id[10];    void out();    void in();};
void A::out(){cout<<key<<endl<<id;}void A::in(){cin>>key;cin>>id;}

主函数申请动态数组对象,并逐一输入:

void main(){int n;cin>>n;A *p=new A[n];for(int i=0;i,n;i++){p[i].in();}//未结束



到此为止用户已经乱序输入了n个对象数组,所有的数据都在内存当中,接下来我们要对其按成员变量key进行排序。方法还是冒泡排序,不同的是临时变量的数据类型和if的判定内容
这里得讲一个常规,如果对一个类定义了两个或多个对象,则这些同类的对象之间可以互相赋值,或者说,一个对象的值可以赋给另一个同类的对象。这里所指的对象的值是指对象中所有数据成员的值。也就是说我们可以通过赋值运算符“ = ”直接用一个对象来赋值另一个同类的对象,于是这个冒泡里用于临时存放数据的对象可声明为A temp,于是按照冒泡排序的算法有如下代码:

for(int j=0;j<n;j++)for(int k=0;k<n-j-1;k++){if(p[k].key>p[k+1].key)//这个判定条件的话就是升序了{A temp=p[k];p[k]=p[k+1];p[k+1]=temp;}}

对象之间的赋值要遵循以下规则:
1、对象的赋值只对其中的数据成员赋值,而不对成员函数赋值。数据成员是占存储空间的,不同对象的数据成员占有不同的存储空间,赋值的过程是将一个对象的数据成员在存储空间的状态复制给另一对象的数据成员的存储空间。而不同对象的成员函数是同一个函数代码段,不需要、也无法对它们赋值。
2、类的数据成员中不能包括动态分配的数据,否则在赋值时可能出现严重后果。

有的同学可能会想到通过交换指针来完成冒泡,然而着这里是不行的。p是这段空间的首地址,并不能间接访问到对象所有内容,所以如*(p+1)这种方式访问对象是错的。因为p[n]本身就是一个对象而非指针,所以访问每个对象只需用p[i]这种方式就可以了。
好的,经以上的步奏以后,就可以以下标升序的形式输出每个对象,并切每个对象按要求的key升序输出:
for(int s=0;s<n;s++){p[s].out();}
delete[] p;}//main函数结束









若有不正确的地方欢迎留言指正





0 0