1 / 44

Unit 8— 第 六 章 模板

Unit 8— 第 六 章 模板. 6.1 模板与数据结构. 6.4 模板与类参数. 6.5 函数指针与指针识别(选读). 6.2 类模板与排序查找. 6.3 索引查找与指针数组. 例 6.3 顺序表类模板设计. template < typename T, int size> class seqlist { T slist [size]; // 存放顺序表的数 组 int Maxsize ; // 最大可容纳项数 int last; // 已存表项的最后位置 public :

cecil
Download Presentation

Unit 8— 第 六 章 模板

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Unit 8—第六章 模板 6.1 模板与数据结构 6.4 模板与类参数 6.5 函数指针与指针识别(选读) 6.2 类模板与排序查找 6.3 索引查找与指针数组

  2. 例6.3 顺序表类模板设计 template<typenameT,int size>classseqlist { T slist[size]; //存放顺序表的数组 intMaxsize; //最大可容纳项数 int last; //已存表项的最后位置 public: seqlist(){last=-1;Maxsize=size;} //初始化为空表 int Length() const{return last+1;} //计算表长度 int Find(T & x)const; // 寻找x在表中位置(下标) boolIsIn(T & x); //判断x是否在表中 bool Insert(T & x,int i); //x插入到列表中第i个位置处(下标) bool Remove(T & x); //删除X int Next(T & x); //寻找X的后续位置 int Prior(T & x); //寻找x的前驱位置 boolIsEmpty(){return last==-1;} //判断表是否空 boolIsFull(){return last==Maxsize -1;} //判断表是否满 T Get(inti){return i<0||i>last?NULL:slist[i];} //取第i个元素之值 T& operator[](int i); }; //重载下标运算符[] classseqlist { intslist[size]; //存放顺序表的数组,size需定义为常量 intMaxsize; //最大可容纳项数 int last; //已存表项的最后位置 public: seqlist(){last=-1;Maxsize=size;} //初始化为空表 int Length() const{return last+1;} //计算表长度 intFind(int& x)const; // 寻找x在表中位置(下标) boolIsIn(int& x); //判断x是否在表中 boolInsert(int& x,inti); //x插入到列表中第i个位置处(下标) boolRemove(int& x); //删除X intNext(int& x); //寻找X的后续位置 intPrior(int& x); //寻找x的前驱位置 boolIsEmpty(){return last==-1;} //判断表是否空 boolIsFull(){return last==Maxsize -1;} //判断表是否满 intGet(inti){return i<0||i>last?NULL:slist[i];} //取第i个元素之值 int& operator[](int i); }; //重载下标运算符[]

  3. 例6.3 顺序表类模板设计 template <typenameT,intsize> intseqlist<T,size>::Find(T & x)const{//const成员函数,表明对象的数据只能读不能写。 int i=0; while(i<=last && slist[i]!=x) i++; //顺序查找是否有x if (i>last) return -1; //未找到,返回-1 else return i; //找到,返回下标 } template <typenameT,int size> boolseqlist<T,size>::IsIn(T & x){ int i=0; bool found=0; while(i<=last && !found) //换了一种方法来查找 if (slist[i]!=x) i++; else found=1; //找到 return found;}

  4. 例6.3 顺序表类模板设计 template <typenameT,int size> T& seqlist<T,size>::operator[] (int i){ if(i<0||i>=Maxsize){ cout<<"下标出界!"<<endl; exit(1); } while(i>last) last++; //数组最大下标增长到i returnslist[i]; } 对P194作了调整! • assert(!(i<0||i>=Maxsize)); 有没有其他方式? 对P194作了调整!

  5. 例6.3 顺序表类模板设计 template <typenameT,int size> boolseqlist<T,size>:: Insert(T & x, int i) { intj; if (i<0||i>last+1||last==Maxsize -1) returnfalse; //插入位置不合理,不能插入(健壮性) else{ last++; for(j=last;j>i;j--) slist[j]=slist[j-1]; //从表最后位置向前依次后移,空出指定位置来 slist[i]=x; return true; } }

  6. 例6.3 顺序表类模板设计 template <typenameT,intsize>boolseqlist<T,size>::Remove(T & x){ inti=Find(x),j; //先去找x在哪个位置 if(i>=0){ last--;//预先将last前移一位 for(j=i;j<=last;j++) slist[j]=slist[j+1]; //依次前移,保证表连续 return true; } return false; //表中不存在x }

  7. 例6.3 顺序表类模板设计 template <typenameT,int size> intseqlist<T,size>::Next(T & x){ inti=Find(x); if(i>=0 && i<last) return i+1; //x后继位置 else return -1; //x不在表中,或在表末尾 } template<typenameT,int size> intseqlist<T,size>::Prior(T & x){ inti=Find(x); if(i>0 && i<=last) return i-1; //x前驱的位置 else return -1; }

  8. 例6.3 顺序表类模板设计 intmain(){ seqlist<int,100> seqlisti; //seqlisti的元素为整型 inti,j,k,a[10]={2,3,5,7,11,13,17,19,23,29}; for(j=0;j<10;j++)//把素数写入 if(!seqlisti.Insert(a[j],j)){ cout<<“表太小放不下了!"<<endl;break;} j=seqlisti.Length(); for(i=0;i<j;i++) cout<<seqlisti.Get(i)<<' '; cout << endl ;//打印出seqlisti.slist[]-素数表 for(j=0;j<10;j++) seqlisti[j]=0; //采用下标运算符运算 for(j=0;j<10;j++) cout<<seqlisti[j]<<' '; cout<<endl; for(j=0;j<10;j++) seqlisti[j]=a[j];

  9. 例6.3 顺序表类模板设计 seqlisti[10]=31; //检验能否增加元素,正确!! for(j=0;j<11;j++) cout<<seqlisti[j]<<' '; cout<<endl; k=7; if (seqlisti.IsIn(k)) cout<<"7在表中"<< endl; //因形参为引用,所以实参不可用整数常量7 elsecout<<"7不在表中"<<endl; k=17; if (seqlisti.Remove (k)) cout<<"删除17"<<endl; //删除17 elsecout<<"找不到17,无法删除"; j=seqlisti.Length( ) ; for (i=0;i<j;i++) cout<<seqlisti.Get(i) <<' '; //打印剩下的素数 cout<<endl;

  10. 例6.3 顺序表类模板设计 if (seqlisti.Insert(k,j-1)){ // 把素数17装回去,成功则打印 j=seqlisti.Length ( ); for (i=0;i<j;i++) cout<<seqlisti.Get(i) <<' '; cout<<endl; } cout<<"打印17后一个素数:“ <<seqlisti.Get(seqlisti.Next(k))<<endl; cout<<"打印17前一个素数:" <<seqlisti.Get(seqlisti.Prior(k))<<endl; cout<<"素数17在表中位置(下标)为:" <<seqlisti.Find(k)<<endl; if(seqlisti.IsEmpty()) cout<<"表是空的"<<endl; else cout<<"表不空"<<endl; if (seqlisti.IsFull()) cout<<"表是满的"<<endl; else cout<<"表也不满"<<endl; if (seqlisti.IsIn(k)) cout<<"素数17在表中"<<endl; return 0; }

  11. 6.1.2 类模板与数据结构—单链表 单链表类模板设计 回忆结点类: typedefintDataType; class Node { DataType info;//数据域 Node *link;//指针域 public: Node();//生成空结点的构造函数 Node(constDatatype &);//生成一般结点的构造函数 voidPrintNode(); //打印当前结点的信息域 friend class SLList;//以SLList为Node友元类,SLList可直接访问Node私有数据,比结构安全 }; 结点类模板: template <typenameDataType> class SLList; template <typenameDataType> class Node { DataType info;//数据域 Node <DataType> *link; //指针域 public: Node();//生成空结点的构造函数 Node(constDatatype &);//生成一般结点的构造函数 voidPrintNode(); //打印当前结点的信息域 friend class SLList <DataType>;//以SLList为Node友元类,SLList可直接访问Node私有数据,比结构安全 }; tail info0 info1 infon-1 ^ …… head

  12. 6.1.2 类模板与数据结构—单链表 template <typenameDataType> Node<DataType>::Node(){ link=NULL; } template <typenameDataType> Node<DataType>::Node(constDataType & data){ info=data; link=NULL; } template <typenameDataType> voidNode<DataType>:: PrintNode(){ cout<<info<<endl; } Node::Node() { link=NULL; } Node::Node(constDataType & data){ info=data; link=NULL; } voidNode::PrintNode(){ cout<<info<<endl; }

  13. 6.1.2 类模板与数据结构—单链表 链表类模板设计 class SLList{ Node *head,*tail;//链表头指针和尾指针 public: SLList();//构造函数,生成头结点(空链表) ~SLList();//析构函数 void MakeEmpty();//清空链表,只余表头结点 Node* TravFind(DataType); //搜索数据域与data相同的结点,返回该结点的地址 void PrintSLL();//打印链表的数据域 void GrowUP(constDataType &);//链表向前生长 void GrowDN(constDataType &);//链表向后生长 void RemoveAft(Node*);//删除结点后的结点 void RemoveCur(Node*); //删除指定结点 }; template <typenameDataType>class SLList{ Node <DataType> *head,*tail;//链表头指针和尾指针 public: SLList();//构造函数,生成头结点(空链表) ~SLList();//析构函数 void MakeEmpty();//清空链表,只余表头结点 Node<DataType> * TravFind(DataType); //搜索数据域与data相同的结点,返回该结点的地址 void PrintSLL();//打印链表的数据域 void GrowUP(constDataType &);//链表向前生长 void GrowDN(constDataType &);//链表向后生长 void RemoveAft(Node <DataType> *);//删除结点后的结点 void RemoveCur(Node <DataType> *); //删除指定结点 };

  14. 6.1.2 类模板与数据结构—单链表 链表类模板成员函数: template <typenameDataType>SLList<DataType>::SLList(){ head=tail=new Node<DataType> (); } template <typenameDataType>SLList<DataType>:: ~SLList(){ MakeEmpty(); delete head; head=NULL; } template <typenameDataType>voidSLList<DataType>:: MakeEmpty(){ Node<DataType>*p; while(head->link!=NULL) { //将链表结点从链中脱离 p=head->link; head->link=p->link; delete p; p=NULL; //删除(释放)脱离下来的结点 } tail=head; //表头指针与表尾指针均指向表头结点,表示空链 }

  15. 6.1.2 类模板与数据结构—单链表 template <typenameDataType>Node <DataType>* SLList<DataType>:: TravFind(DataTypekey){ Node<DataType>*p=head->link; while(p!=NULL&&p->info!=key)p=p->link; return p;//搜索成功返回该结点地址,不成功返回NULL } template <typenameDataType>void SLList<DataType>:: PrintSLL() { //显示链表 Node<DataType>* p=head->link; while(p!=NULL) { cout<<p->info<<'\t'; p=p->link; } cout<<endl; }

  16. 6.1.2 类模板与数据结构—单链表 template <typenameDataType>void SLList<DataType>:: GrowUP(constDataType& data){ Node<DataType>*p=new Node<DataType> (data); p->link=head->link; head->link=p; //新结点始终在头结点之后 } template <typenameDataType>void SLList<DataType>:: GrowDN(constDataType& data){ Node<DataType>* p=new Node<DataType>(data); tail->link=p; tail=p; tail->link=NULL; }

  17. 6.1.2 类模板与数据结构—单链表 template <typenameDataType>void SLList<DataType>:: RemoveAfter(Node<DataType>*p){ Node<DataType>*q; q=p->link; if(q!=NULL){ p->link=q->link; deleteq; q=NULL;} } template <typenameDataType>void SLList<DataType>:: RemoveCur(Node<DataType>*p){ Node<DataType>*q=head; while(q->link!=NULL && q->link!=p) q=q->link;//遍历查找 if(q->link==tail) tail=q;//已经找到末尾 RemoveAfter(q);//删除q后面的结点p }

  18. 6.1.2 类模板与数据结构—单链表 测试: voidintmain(){ SLList<int>L1; Node<int>n, *tmp; for(int j=0;j<10;j++) L1.GrowDN(j); //向后生成链表 cout<<"初始链表:"; L1.PrintSLL(); //打印表 L1.GrowUP(20);//向前插入到头结点后 cout<<"插入结点后的链表:";L1.PrintSLL(); //打印 tmp=L1.TravFind(20); //查找插入的结点 n=*tmp; cout<<"找到结点的信息域:"; n.PrintNode(); L1.RemoveCur(tmp);//删除插入的结点 cout<<"删除结点后的链表:";L1.PrintSLL();//打印 return 0; } 类到类模板的设计要点: (1)将类中潜在可变的数据类型或者常量,替换为模板参数,设计模板头; (2)查找类中包含的其他类模板,将类名后加<模板参数名表>,便于随后的实例化。

  19. 6.1.2 类模板与数据结构—栈 顺序栈类模板设计: template <typenameDataType, intsize> class Stack{ inttop; //栈顶(下标) DataType *elements; //指向动态建立的栈 intmaxSize; //栈最大容纳的元素个数 public: Stack(); //构造函数 ~Stack(){delete[ ] elements; elements=NULL;} void Push(constDataType &); //压栈, top++ DataType Pop(); //弹出,top-- DataTypeGetElem(int); //随机取数据,top不变 void MakeEmpty(){top= -1;} //清空栈 boolIsEmpty() const{return top== -1;} //判栈空 boolIsFull() const{return top==maxSize-1;} //判栈满 void PrintStack(); //输出栈内所有数据 }; class Stack{ inttop; //栈顶(下标) DataType *elements; //指向动态建立的栈 intmaxSize; //栈最大容纳的元素个数 public: Stack(constint&size=20); //构造函数, top= -1 ~Stack(){delete[ ] elements; elements=NULL;} void Push(constDataType &); //压栈, top++ DataType Pop(); //弹出,top-- DataTypeGetElem(int); //随机取数据,top不变 void MakeEmpty(){top= -1;} //清空栈 boolIsEmpty() const{return top== -1;} //判栈空 boolIsFull() const{return top==maxSize-1;} //判栈满 void PrintStack(); //输出栈内所有数据 }; 退栈 压栈 top an-1 top an-2 …… top a1 top a0 top bottom

  20. 6.1.2 类模板与数据结构—栈 template <typenameDataType , intsize > Stack<DataType, size >::Stack () { maxSize=size; top=-1; elements=newDataType [maxSize]; //建立栈空间 assert(elements!=NULL); //假定未悬空,否则分配失败,结束 } template <typenameDataType , intsize > void Stack<DataType,size>:: PrintStack(){ for(inti=0;i<=top;i++) cout<<elements[i]<<'\t'; cout<<endl; } template <typenameDataType , intsize > void Stack<DataType,size>:: Push(constDataType &data){ assert(!IsFull()); //栈满则退出程序 elements[++top]=data; //栈顶下标先加1,元素再进栈 }

  21. 6.1.2 类模板与数据结构—栈 template <typenameDataType , intsize > DataType Stack <DataType,size>:: Pop(){ assert(!IsEmpty()); //栈已空则不能退栈,退出程序 return elements[top--]; //返回栈顶元素,同时栈顶下标-1 } template <typenameDataType , intsize > DataTypeStack <DataType,size>:: GetElem(inti){ assert(i<=top&&i>=0); //超出栈有效数据区,则退出程序 return elements[i]; //返回指定元素,top不变 }

  22. 6.1.2 类模板与数据结构—栈 测试: intmain(){ inti,a[10]={0,1,2,3,4,5,6,7,8,9},b[10]; Stack <int, 10>istack(); for(i=0;i<10;i++) istack.Push(a[i]); //压栈 if(istack.IsFull()) cout<<"栈满"<<endl; istack.PrintStack(); for(i=0;i<10;i++) b[i]=istack.Pop(); if(istack.IsEmpty()) cout<<"栈空"<<endl; for(i=0;i<10;i++) cout<<b[i]<<'\t'; //注意先进后出 cout<<endl; istack.Pop(); //弹出报错 return 0; }

  23. 6.1.2 类模板与数据结构—队列 front rear tail a0 a1 an 链队实现方式 head …… …… ^ a0 a1 a2 … … an-1 rear front 链队类模板设计: Node和SLList类模板设置: template <typenameDataType> class SLListQueue; template <typenameDataType> class Node { (略) friendclass SLListQueue<DataType>; }; template <typenameDataType> class SLList{ (略) friendclass SLListQueue<DataType>; };

  24. 6.1.2 类模板与数据结构—队列 template <typenameDataType> classSLListQueue { SLList<DataType>LstQue; Node <DataType>*front,*rear; public: SLListQueue(){front=rear=LstQue.head->link;} //空链队 ~SLListQueue(){} //析构函数 boolIsEmpty(){ returnLength()==0;} //队空否? voidEnQue(constDataType &); //进队 DataTypeDeQue(); //出队 DataTypeGetFront(); //查看队头数据 voidMakeEmpty(); //置空队列 };

  25. 6.1.2 类模板与数据结构—队列 template <typenameDataType> DataTypeSLListQueue<DataType>:: DeQue(){ …… } template <typenameDataType> DataTypeSLListQueue<DataType>:: GetFront(){ …… } template <typenameDataType> voidSLListQueue<DataType>:: MakeEmpty(){ …… } 链队类模板可以继承链表类模板吗? 继承的思想不适应类模板设计;各模板独立设计,但可以使用聚合概念!

  26. 6.2 类模板与排序查找 查找(search): 按关键字(key word),在有序的数据集合(顺序表,升序或降序)中,寻找满足条件的数据。 算法:对半查找(迭代、递归)

  27. 6.2.1类模板与查找方法 mid high 20 21 23 26 29 31 37 39 high low mid low 图6.3 查找成功例 23 成功 low mid high 2 5 7 8 9 11 13 17 19 20 21 23 26 39 37 29 31 low 23 查找 20 21 23 mid high 对半查找: 以变量low和high为数据序列的首尾元素的下标,取mid= (low+ high)/2,如mid位置的元素是所查找的,则结束。如果该元素大了,则取low=mid +1, high不变,继续查找;如果该元素小了,则取 high=mid-1,low不变,继续查找。如果查到low>=high仍未找到,则失败,停止。

  28. 6.2.1类模板与查找方法 mid high mid high mid high 9 图6.4 查找失败例 low mid high 10 2 2 5 5 7 7 8 8 9 9 9 11 11 11 13 13 13 17 17 17 19 20 29 31 21 23 37 26 39 查找 low low low 注意: (1)区间收缩过程中,low=mid+1和high=mid-1非常重要,没有“+1”和“-1”时,可能数据存在却找不到。 (2)对半查找递归算法与迭代算法。

  29. 作为有序表类模板成员函数: template<typenameT,int size> intOrderedlist<T,size> :: Binarysearch (const T & x, constintlow, constint high){ int mid=-1; if (low<=high) { mid=(low+high)/2; if (slist[mid]<x) mid = Binarysearch(x,mid+1,high); //中间点小于X,查找右区间,注意mid+1 elseif(x<slist[mid]) mid=Binarysearch(x,low,mid-1); //中间点大于X,查找左区间,注意 mid-1 } returnmid;//找到返回下标;未找到但结束了,返回-1 } 【例6.4】对半查找递归算法

  30. 有序表基本元素为类Element对象 : class Element{ intkey; // 其他域省略 public: bool operator<(Element ele){return key<ele.key;} voidsetkey(intk){key=k;} void show(){cout<<key<<'\t';} }; //重载了比较运算符,元素的比较实际是元素关键字的比较 template <typenameT,int size>classOrderedlist{ intmaxsize; intlast; T slist[size]; public: Orderedlist(){last=-1;maxsize=size;} intBinarysearch(T & x,constintlow,constint high); boolInsert(T & elem,inti); void print(); // 无关成员函数省略 };

  31. 【例6.4】对半查找递归算法 template <typenameT,intsize>boolOrderedlist<T,size>:: Insert(T & elem ,int i){ intj; if(i<0||i>last+1||last==maxsize-1) return false;//”前驱后继” else{ last++; for (j=last;j>i;j--) slist[j]=slist[j-1]; slist[i]=elem; return true;} } template <typenameT,int size> voidOrderedlist<T,size>:: print(){ inti; for(i=0;i<=last;i++){ slist[i].show(); if(i%5==4) cout<<endl;} cout<<endl; }

  32. 【例6.4】对半查找递归算法 int main(){ constint h=19;inti,k=37; Orderedlist<Element,100> ordlist; int a[h]={67,61,59,53,47,43,41,37,31,29,23, 19,17,13,11,7,5,3,2}; //降序 Element n[h],elem; for(i=0;i<h;i++) n[i].setkey(a[i]);//初始化关键字 for(i=0;i<h;i++) ordlist.Insert(n[i],0); //始终在0下标位置插入,建立升序顺序表 ordlist.print(); elem.setkey(k); i=ordlist.Binarysearch(elem,0,h-1); cout<<"整数"<<k<<"在表中位置:"<<i<<endl; return 0;}

  33. 【例6.5】对半查找迭代算法 template<typenameT,int size > intOrderedlist<T,size>:: BinarySearch(constT & x) const{ int high=last, low=0, mid;// last 当前有序表最大下标 if ( last ==- 1 ) return -1; //避免空表出错 while (low<=high ) { mid = (low+high)/2; if ( x<slist[mid] ) high = mid-1; //左缩查找区间 elseif ( slist[mid]<x ) low = mid+1; // 右缩查找区间 elsereturn mid; } if ( slist[mid] != x ) mid = -1; // 未找到 return mid; }

  34. 6.2.2 常用的排序法 • 排序(sorting): • 按照数据元素的可排序数据项(关键字)的大小,排列成升序或降序的数据序列的过程。排序是查找的前提。 • 算法:插入排序(直接、对半);交换排序(冒泡排序);选择排序(直接选择排序)

  35. 直接插入排序(升序)的思想: 当取得元素s[i](i>0)时,前面的元素s[0],s[1],…, s[i-1]已经排好序,我们将s[i]的关键字与s[i-1], s[i-2],…,的关键字顺序进行比较,找到第一个比它小的,则s[i]插到该元素之后。 6.2.2 常用的排序法——直接插入排序

  36. 作Orderedlist<T,size>类成员函数,T为数组元素类型作Orderedlist<T,size>类成员函数,T为数组元素类型 template<typenameT,int size>voidOrderedlist<T,size>:: InsertSort(){ T temp; inti,j; for (i=1;i<=last;i++){ temp=slist[i]; j=i; while (j>0&&temp<slist[j-1]){ slist[j]=slist[j-1]; j--; //查找与移动同时做 } slist[j]=temp; } } 【例6.6】升序直接插入排序算法

  37. 有序表类Orderedlist<T,size>的基本元素为Element类对象,Element类定义类似(key类型改为string),略。 voidmain(){ constint h=10; Element n[h]; inti; Orderedlist<Element,100> ordlist; string mslist[h]={"cat","book","car","zoo","fish", "cab","dog","cap","fox","can"}; for(i=0;i<h;i++) n[i].setkey(mslist[i]); for(i=0;i<h;i++) ordlist.Insert(n[i],i); //建立顺序表 cout<<"未排序表:"<<endl; ordlist.print(); ordlist.InsertSort(); cout<<"已排序表:"<<endl; ordlist.print(); } 【例6.6】升序直接插入排序算法

  38. 交换排序基本思想: 按关键字两两排序,如果发生逆序则交换之,直到所有的数据都排好为止。 6.2.2 常用的排序法——交换排序 图6.6从下往上冒泡排序 冒泡排序:(1)首先从一列数据底部(下标last)开始,相邻两数据进行比较,小的放上面,一趟下来,最小的数据冒到最上面;(2)缩小区域,按同样方法继续下一趟交换;(3)如果有一趟比较中没有发生交换,则已排好序。

  39. template<typename T, intsize> void Orderedlist<T,size>:: BubbleSort(){ boolnoswap; int i, j; T temp; for ( i=0; i<last; i++ ) { //最多做last趟 noswap=true; //“未交换”标志为真 for ( j=last; j>i; j--) { //从下往上冒泡 if ( slist[ j ] < slist[ j-1 ] ) { temp = slist[ j ]; slist[ j ] = slist[ j-1 ]; slist[ j-1 ] = temp; noswap = false; } } if ( noswap ) break; //本趟无交换,则终止算法。 } } 【例6.8】冒泡排序算法

  40. 【例6.8】冒泡排序算法 student类对象为数组的元素 class student{ intid; //学号(主关键字) int age; //年龄 string name; // 姓名 char sex; // 性别 string address; //家庭地址 float eng, phy, math, electron; //英语,物理,数学和电子成绩 public: student(){} student(int,string,char,int,string,float,float,float,float); booloperator<(student ele){return id<ele.id;}//比较符重载 void show(){ cout<<id<<'\t'<<name<<'\t'<<sex<<'\t' <<age <<'\t' <<address<<'\t'<<eng<<'\t'<<phy<<'\t'<<math<<'\t'<<electron<<endl;} };

  41. 【例6.8】冒泡排序算法 intmain(){ constinth=4; inti; Orderedlist<student,100> ordlist; student n[h]={ student(6004327,"张菲",'m',19,"北京路58号",80,85,90,78), student(6004121,"关雨",'w',19,"天津路64号",88,75,91,68), student(6004118,"刘蓓",'w',18,"上海路37号",78,95,81,88), student(6004219,"赵昀",'m',18,"重庆路95号",78,95,81,88)}; for(i=0;i<h;i++) ordlist.Insert(n[i],i); //建立顺序表 cout<<"未排序表:"<<endl; ordlist.print(); ordlist.BubbleSort(); cout<<"已排序表:"<<endl; ordlist.print(); return 0; }

  42. 选择排序(Selection Sort): 每一趟从记录中选出关键字最小的元素,顺序放在已排好序的子序列前面,直到全部记录排序完成。直接选择排序(Straight Selection Sort)是最简单方法。 6.2.2 常用的排序法——直接选择排序 [49 38 65 97 76 13 27 49’]  13 [38 65 97 76 49 27 49’]  13 27 [65 97 76 49 38 49’] 13 27 38 [97 76 49 65 49’]  13 27 38 49 [76 97 65 49’]  13 27 38 49 49’ [9765 76]  13 27 38 49 49’ 65 [9776]  13 27 38 49 49’ 65 76 97 图6.7直接选择排序的过程

  43. 【例6.9】直接选择排序 • template<typenameT,intsize>void Orderedlist<T,size>:: SelectSort(){ • int i, j, k; T temp; • for(i=0;i<last;i++){ • k=i; temp=slist[i]; • for(j=i+1;j<=last;j++)//课本j=i有误,多了趟自己比 • if(slist[j]<temp) • { k=j; temp=slist[j]; } • if ( k != i ){ • temp=slist[i]; • slist[i]=slist[k]; • slist[k]=temp; • } • } • }

  44. Unit 8—第六章 模板 6.1 模板与数据结构 6.4 模板与类参数 6.5 函数指针与指针识别(选读) 6.2 类模板与排序查找 6.3 索引查找与指针数组

More Related