实验六 排序
(1)实验要求:
掌握常用的排序方法及其实现方法;深刻理解排序的定义和各种排序方法的特点,并能加以灵活应用;了解各种方法的排序过程及其依据的原则,并掌握各种排序方法的时间复杂度的分析方法。
(2)实验内容:
给出n个学生的考试成绩表,每条信息由姓名和成绩组成,试运用各种排序思想设计算法并比较其性能,要求实现:
a.按分数高低次序,打印出每个学生在考试中获得的名次,分数相同的为同一名次;
b.按名次列出每个学生的姓名与分数。
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
#include<string.h>
#define MAX 100
using namespace std;
typedef struct {
int score;
string name;
}Std;
typedef struct {
Std r[MAX];
int length;
}Sqlist;
void Input(Sqlist &L){ //输入
int i;
printf( "输入表的长度:\n" );
scanf( "%d", &L.length );
printf( "输入名字和成绩\n" );
for( i=1; i<=L.length; i++ ){
cin>>L.r[i].name;
cin>>L.r[i].score;
}
}
void Output( Sqlist L ) //输出表中的元素
{
int i,k=1;
printf("名次 姓名 成绩\n");
for( i = 1; i <= L.length; i++,k++ ){
if(L.r[i].score==L.r[i-1].score)
k--;
cout<<k<<" "<<L.r[i].name<<" "<<L.r[i].score;
printf("\n");
}
}
//直接插入排序
void InsertSort(Sqlist &L)
{
cout<<"对待排序序列L进行直接插入排序"<<endl;
int i,j;
for(i=2; i<=L.length; ++i)
if (L.r[i].score < L.r[i-1].score){ //比较
L.r[0] = L.r[i]; // 复制为哨兵
for(j = i-1; L.r[0].score< L.r[j].score; --j)
L.r[j+1] = L.r[j]; // 记录后移
L.r[j+1] = L.r[0]; //记录插入
}
} // InsertSort
/*
void BubbleSort( Sqlist &L ) {
//对顺序表L作冒泡排序(从下往上做比较)
int i,j;
int move;
for(i=2; i<=L.length; i++) { //进行n-1趟扫描
move=0 ; //move是交换与否的标志
for( j=L.length; j>=i; j--)
if( L.r[j].score < L.r[j-1].score ) {
swap(L.r[j],L.r[j-1]);
move=1;
} //如逆序则交换
if ( !move ) break; //如果没有移动发生,则结束
}
}*/
void BubbleSort( Sqlist &L ) {
//对顺序表L作冒泡排序(从上往下做比较)
cout<<"对顺序表L作冒泡排序"<<endl;
int i,j;
int move;
for(i=1; i<L.length; i++) { //进行n-1趟扫描
move=0 ; //move是交换与否的标志
for( j=1; j<=L.length-i; j++)
if( L.r[j].score>L.r[j+1].score ) {
swap(L.r[j],L.r[j+1]);
move=1;
} //如逆序则交换
if ( !move ) break; //如果没有移动发生,则结束
}
}
//快速排序
int Partition( Sqlist &L, int low, int high ) {
//对排序区间L.R[low..high]进行一次分区,返回基准位置下标
L.r[0]=L.r[low];
int pivotkey=L.r[low].score;
while(low<high) {
while(low<high&&L.r[high].score>=pivotkey)
--high;
L.r[low] = L.r[high]; // 比基准小的记录左移
while(low<high&&L.r[low].score<=pivotkey)
++low;
L.r[high] = L.r[low]; // 比基准大的记录右移
}
L.r[low] = L.r[0]; //基准到位
return low; //返回基准的位置下标
}
void QSort( Sqlist &L, int low, int high ) {
//对排序区间L.R[low..high]进行快速排序(P275, 算法10.7)
int pivotloc;
if( low < high ) {
pivotloc=Partition( L, low, high ); //进行分区,返回基准下标
QSort(L, low, pivotloc-1) ; // 对左半区进行快速排序
QSort(L, pivotloc+1, high) ; // 对右半区进行快速排序
}
}
void QuickSort( Sqlist &L) {
// 对整个顺序表进行快速排序(P276, 算法10.8)
QSort( L, 1, L.length );
}
//希尔排序
void ShellInsert(Sqlist &L,int dk){
int i,j;
for( i=dk+1;i<=L.length;i++)
if(L.r[i].score<L.r[i-dk].score){
L.r[0]=L.r[i];
for( j=i-dk; j>0&&L.r[0].score<L.r[j].score; j-=dk )
L.r[j+dk]=L.r[j];
L.r[j+dk]=L.r[0];
}
}
void ShellSort(Sqlist &L){
cout<<"**********希尔排序**********"<<endl;
int t;
cout<<"请输入增量个数"<<endl;
cin>>t;
int dlta[t];
cout<<"请输入"<<t<<"个增量"<<endl;
for(int i=0;i<t;i++)
cin>>dlta[i];
for(int k=0;k<t;k++)
ShellInsert(L,dlta[k]);
}
int main()
{
Sqlist L;
Input(L);
cout<<"排序前"<<endl;
Output(L);
//InsertSort(L);
//BubbleSort(L);
//QuickSort(L);
ShellSort(L);
cout<<"排序后"<<endl;
Output(L);
return 0;
}
堆排序
#include<iostream>
#include<iomanip>
#define MAXSIZE 8
typedef int KeyType;
using namespace std;
typedef struct{
KeyType key;
}RedType;
typedef struct SqList{
RedType r[MAXSIZE+1];//r[0]闲置或用作哨兵
int length;
}SqList;
typedef SqList HeapType; //堆采用顺序表存储表示
void HeapAdjust(HeapType &H,int s,int m){
//已知H.r[s...m]中记录关键字除H.r[s].key之外均满足堆的定义,本函数调整
//H.r[s]的关键字,使H.r[s...m]成为一个大顶堆
RedType rc=H.r[s];
for(int j=2*s;j<=m;j*=2){//沿key较大的孩子节点向下筛选
if(j<m&&H.r[j].key<H.r[j+1].key) ++j; //找到孩子节点中较大的一个
if(rc.key>H.r[j].key) break; //要筛选的节点如果比左右孩子的值都大的话说明他本来就是一个大顶堆,所以break
H.r[s]=H.r[j];
s=j;
}
H.r[s]=rc; //将要调整的关键字的值放在正确的位置上
}
void HeapSort(HeapType &H){
//对顺序表进行堆排序
for(int i=H.length/2;i>0;i--){
HeapAdjust(H,i,H.length);
}//把H.r[1..H.length]建成大顶堆
cout<<"排序后的大顶堆进行层次遍历:"<<endl;
for(int i=1;i<=MAXSIZE;i++)
cout<<setw(4)<<H.r[i].key;
cout<<endl;
cout<<"依次输出堆顶元素"<<endl;
for(int i=H.length;i>=1;i--){
cout<<setw(4)<<H.r[1].key;//输出堆顶元素
swap(H.r[1],H.r[i]); //将堆顶元素与最后一个元素进行交换
HeapAdjust(H,1,i-1); //重新调整为大顶堆
}
}
int main(){
HeapType H;
H.length=MAXSIZE;
cout<<"请输入"<<MAXSIZE<<"个元素"<<endl;
for(int i=1;i<=MAXSIZE;i++) //空出r[0]的位置
cin>>H.r[i].key;
HeapSort(H);
return 0;
}