【数据结构】——排序

简介: 【数据结构】——排序

🎯目的:

1、掌握排序的有关概念和特点。


2、熟练掌握直接插入排序、折半插入排序、冒泡排序、简单选择排序等算法的基本思想。


3、熟练掌握希尔排序、快速排序、堆排序、归并排序、基数排序等算法的基本思想,能够使用程序实现希尔排序、快速排序。


4、关键字序列有序与无序,对于不同的排序方法有不同的影响,通过该实验进一步加深理解。


🎯内容:

设有学生信息表{姓名,成绩}:{{aaa,87},{bbb,76},{ccc,92},{ddd,64},{eee,55},{fff,78},{ggg,100},{hhh,43}},试用不同排序算法进行排序。


🎯环境:

TC或VC++。


🎯步骤:

1、使用顺序结构存储学生信息(注意下标从1开始),并输出值。


2.将学生信息按成绩进行排序,输出各种排序算法每一趟排序的结果,观察关键字次序的变化。


(1)直接插入排序算法;

(2)折半插入排序算法;

(3)冒泡排序算法;

(4)简单选择排序的算法。

(5)希尔排序算法;

(6)快速排序算法。

💻分部解析:

💎导入头文件和命名空间

#include <iostream>
#include "cstring"
using namespace std;


       该语句块中,使用了两个头文件,一个是 iostream,用于输入输出操作;另一个是 cstring,用于字符串操作。使用 using namespace std 命名空间,可以避免每次都写 std::

💎定义类型

#define MAXSIZE 20
typedef int KeyType;
typedef string InfoType;
typedef struct{
    KeyType key;//关键字项
    InfoType otherinfo;//其他数据项 
}RedType;
typedef struct {
    RedType r[MAXSIZE+1];//r[0]闲置 
    int length;//顺序表长度 
}SqList;

        该语句块中,定义了 MAXSIZE 宏定义常量,KeyType 和 InfoType 类型分别表示关键字类型和其他数据类型,RedType 结构体表示记录,包含关键字项和其他数据项,SqList 结构体表示顺序表,包含记录数组和顺序表长度。


💎输出排序结果函数

//输出语句 
void OutPutSort(SqList L)
{
    for(int i=1;i<=L.length;i++){
        cout << " {" << L.r[i].otherinfo << "," << L.r[i].key << "}";
    }
    cout<<endl;    
}

该语句块中,定义了 OutPutSort 函数,用于输出排序结果。

💎直接插入排序算法

//直接插入排序算法
void InsetSort(SqList L)
{//对顺序表L进行直接插入 
    for(int i=2;i<=L.length;i++)
        if(L.r[i].key<L.r[i-1].key)//"<",需要将r【i】插入到有序子表
        {   
            L.r[0]=L.r[i];//把待插入的暂存到监视哨 
            L.r[i]=L.r[i-1];//后移操作
            int j;
            for(j=i-2;L.r[0].key<L.r[j].key;j--)//往后寻找插入位置
                L.r[j+1]=L.r[j];
            L.r[j+1]=L.r[0];
        }
    cout<<"经过直接插入排序法排序后:"<<endl;
    OutPutSort(L);    
}


该语句块中,定义了 InsetSort 函数,用于对顺序表进行直接插入排序。

💎折半插入排序算法

//折半插入排序
void BInsertSort (SqList L)
{//对顺序表进行折半插入排序 
    int low,high,mid;
    for(int i=2;i<=L.length;i++)
    {
        L.r[0]=L.r[i];//将待插入的记录暂存到监视哨中
        low=1;high=i-1;//置查找区间的初值
        while(low<=high)
        {
            mid=(low+high)/2;
            if(L.r[0].key<L.r[mid].key) high=mid-1;//插入到前一个子表
            else low=mid+1; 
        } 
        for(int j=i-1;j>=high+1;j--)
            L.r[j+1]=L.r[j];//记录后移
        L.r[high+1]=L.r[0];//将r[0]插入到正确位置 
    }
    cout<<"经过折半插入排序后:"<<endl;
    OutPutSort(L);    
}

该语句块中,定义了 BInsertSort 函数,用于对顺序表进行折半插入排序。

💎冒泡排序算法

//冒泡排序算法
void BubbleSort(SqList L)
{
    RedType t;
    int m=L.length-1;int flag=1;//用flag值用来标记某一趟的排序是否交换 
    while((m>0)&&(flag==1)){
        flag=0;//将flag置为0,如果本趟排序没有交换,则不会执行下一趟
        for(int j=1;j<=m;j++){
            if(L.r[j].key>L.r[j+1].key)
            {
                flag=1;
                t=L.r[j];
                L.r[j]=L.r[j+1];
                L.r[j+1]=t;
            }
        }
        m--;
    }
    cout<<"经过冒泡法排序后:"<<endl;
    OutPutSort(L);
}


该语句块中,定义了 BubbleSort 函数,用于对顺序表进行冒泡排序。

💎简单选择排序的算法

//简单选择排序
void SelectSort(SqList L){
    RedType t;
    for(int i=1;i<L.length;i++){//在L.r[i...L.length]中选择最小的记录 
        int k=i;
        for(int j=i+1;j<=L.length;j++){
            if(L.r[j].key<L.r[k].key)
                k=j;//k为中最小的关键字的记录
        }
        if(k!=i)
        {
            t=L.r[i];
            L.r[i]=L.r[k];
            L.r[k]=t;    
        }
    }
    cout<<"经过简单选择排序后:"<<endl;
    OutPutSort(L);
}

该语句块中,定义了 SelectSort 函数,用于对顺序表进行简单选择排序。

💎希尔排序算法

//希尔排序
void ShellInsert(SqList &L,int d){
    for(int i=d+1;i<=L.length;i++)
    if(L.r[i].key<L.r[i-d].key){//需将L.r[i]插入有序增量子表中 
        L.r[0]=L.r[i];//暂存在r[0]中
        int j;
        for(j=i-d;j>0&&L.r[0].key<L.r[j].key;j-=d)
            L.r[j+d]=L.r[j];
        L.r[j+d]=L.r[0]; 
    }
}   
void ShellSort(SqList L,int d[],int t){
    //按增量排序列d[0 ..t-1]
    for(int k=0;k<t;k++){
        ShellInsert(L,d[k]);//每一趟增量为t的希尔排序 
    }
    cout<<"经过希尔排序后:"<<endl;
    OutPutSort(L);
} 


该语句块中,定义了 ShellInsert 函数和 ShellSort 函数,用于对顺序表进行希尔排序。

💎快速排序算法

//快速排序
 int Partition(SqList &L,int low ,int high){
    L.r[0]=L.r[low];//用子表的第一个作为枢轴 
    int pivotkey=L.r[low].key;//将其关键字保存在pivotkey里
    while(low<high)//从表的两端交替向中间查找 
    {
        while(low<high&&L.r[high].key>=pivotkey)
            --high;
        L.r[low]=L.r[high];//将比枢轴记录小的记录移到低位
        while(low<high&&L.r[low].key<=pivotkey)
            ++low;
        L.r[high]=L.r[low];// 将比枢轴记录大的记录移到高位
    }
    L.r[low]=L.r[0];// 枢轴记录到位
    return low;//返回枢纽位置 
 }
 
 void QSort(SqList &L,int low,int high)
 {
    if(low<high){
        int pivotloc=Partition(L,low ,high);//将L.r一分为二,pivotloc是枢轴位置 
        QSort(L,low,pivotloc-1);//对左子表递归排序
        QSort(L,pivotloc+1,high);//对右子表递归排序 
     }
 }
 
void QuickSort(SqList L)
{//对顺序表进行快速排序 
    QSort(L,1,L.length);
    cout<<"经过快速排序后:"<<endl;
    OutPutSort(L);
}


该语句块中,定义了 Partition 函数和 QSort 函数和 QuickSort 函数,用于对顺序表进行快速排序。

💎主函数

int main() {
    // 初始化学生信息表
    SqList L;
    L.r[1].key = 87; L.r[1].otherinfo = "aaa";
    L.r[2].key = 76; L.r[2].otherinfo = "bbb";
    L.r[3].key = 92; L.r[3].otherinfo = "ccc";
    L.r[4].key = 64; L.r[4].otherinfo = "ddd";
    L.r[5].key = 55; L.r[5].otherinfo = "eee";
    L.r[6].key = 78; L.r[6].otherinfo = "fff";
    L.r[7].key = 100; L.r[7].otherinfo = "ggg";
    L.r[8].key = 43; L.r[8].otherinfo = "hhh";
    L.length = 8;
 
    cout << "原始学生信息表:";
    OutPutSort(L);
 
    // 不同排序算法进行排序
       
    InsetSort(L);
  BInsertSort (L);
    BubbleSort(L);
    SelectSort(L);
    int d[] = {5, 3, 1}; // 增量数组d
    ShellSort(L, d, 3);
    QuickSort(L);
 
    return 0;
}


对定义函数进行调用。

💻总代码:

#include <iostream>
#include "cstring"
using namespace std;
 
#define MAXSIZE 20
typedef int KeyType;
typedef string InfoType;
typedef struct{
  KeyType key;//关键字项
  InfoType otherinfo;//其他数据项 
}RedType;
typedef struct {
  RedType r[MAXSIZE+1];//r[0]闲置 
  int length;//顺序表长度 
}SqList;
 
 
//输出语句 
void OutPutSort(SqList L)
{
  for(int i=1;i<=L.length;i++){
    cout << " {" << L.r[i].otherinfo << "," << L.r[i].key << "}";
  }
  cout<<endl; 
}
 
//直接插入排序算法
void InsetSort(SqList L)
{//对顺序表L进行直接插入 
  for(int i=2;i<=L.length;i++)
    if(L.r[i].key<L.r[i-1].key)//"<",需要将r【i】插入到有序子表
    { 
      L.r[0]=L.r[i];//把待插入的暂存到监视哨 
      L.r[i]=L.r[i-1];//后移操作
      int j;
      for(j=i-2;L.r[0].key<L.r[j].key;j--)//往后寻找插入位置
        L.r[j+1]=L.r[j];
      L.r[j+1]=L.r[0];
    }
  cout<<"经过直接插入排序法排序后:"<<endl;
  OutPutSort(L);  
}
 
//折半插入排序
void BInsertSort (SqList L)
{//对顺序表进行折半插入排序 
  int low,high,mid;
  for(int i=2;i<=L.length;i++)
  {
    L.r[0]=L.r[i];//将待插入的记录暂存到监视哨中
    low=1;high=i-1;//置查找区间的初值
    while(low<=high)
    {
      mid=(low+high)/2;
      if(L.r[0].key<L.r[mid].key) high=mid-1;//插入到前一个子表
      else low=mid+1; 
    } 
    for(int j=i-1;j>=high+1;j--)
      L.r[j+1]=L.r[j];//记录后移
    L.r[high+1]=L.r[0];//将r[0]插入到正确位置 
  }
  cout<<"经过折半插入排序后:"<<endl;
  OutPutSort(L);  
}
 
//冒泡排序算法
void BubbleSort(SqList L)
{
  RedType t;
  int m=L.length-1;int flag=1;//用flag值用来标记某一趟的排序是否交换 
  while((m>0)&&(flag==1)){
    flag=0;//将flag置为0,如果本趟排序没有交换,则不会执行下一趟
    for(int j=1;j<=m;j++){
      if(L.r[j].key>L.r[j+1].key)
      {
        flag=1;
        t=L.r[j];
        L.r[j]=L.r[j+1];
        L.r[j+1]=t;
      }
    }
    m--;
  }
  cout<<"经过冒泡法排序后:"<<endl;
  OutPutSort(L);
}
 
//简单选择排序
void SelectSort(SqList L){
  RedType t;
  for(int i=1;i<L.length;i++){//在L.r[i...L.length]中选择最小的记录 
    int k=i;
    for(int j=i+1;j<=L.length;j++){
      if(L.r[j].key<L.r[k].key)
        k=j;//k为中最小的关键字的记录
    }
    if(k!=i)
    {
      t=L.r[i];
      L.r[i]=L.r[k];
      L.r[k]=t; 
    }
  }
  cout<<"经过简单选择排序后:"<<endl;
  OutPutSort(L);
}
 
//希尔排序
void ShellInsert(SqList &L,int d){
  for(int i=d+1;i<=L.length;i++)
  if(L.r[i].key<L.r[i-d].key){//需将L.r[i]插入有序增量子表中 
    L.r[0]=L.r[i];//暂存在r[0]中
    int j;
    for(j=i-d;j>0&&L.r[0].key<L.r[j].key;j-=d)
      L.r[j+d]=L.r[j];
    L.r[j+d]=L.r[0]; 
  }
} 
void ShellSort(SqList L,int d[],int t){
  //按增量排序列d[0 ..t-1]
  for(int k=0;k<t;k++){
    ShellInsert(L,d[k]);//每一趟增量为t的希尔排序 
  }
  cout<<"经过希尔排序后:"<<endl;
  OutPutSort(L);
} 
 
//快速排序
 int Partition(SqList &L,int low ,int high){
  L.r[0]=L.r[low];//用子表的第一个作为枢轴 
  int pivotkey=L.r[low].key;//将其关键字保存在pivotkey里
  while(low<high)//从表的两端交替向中间查找 
  {
    while(low<high&&L.r[high].key>=pivotkey)
      --high;
    L.r[low]=L.r[high];//将比枢轴记录小的记录移到低位
    while(low<high&&L.r[low].key<=pivotkey)
      ++low;
    L.r[high]=L.r[low];// 将比枢轴记录大的记录移到高位
  }
  L.r[low]=L.r[0];// 枢轴记录到位
  return low;//返回枢纽位置 
 }
 
 void QSort(SqList &L,int low,int high)
 {
  if(low<high){
    int pivotloc=Partition(L,low ,high);//将L.r一分为二,pivotloc是枢纽位置 
    QSort(L,low,pivotloc-1);//对左子表递归排序
    QSort(L,pivotloc+1,high);//对右子表递归排序 
   }
 }
 
void QuickSort(SqList L)
{//对顺序表进行快速排序 
  QSort(L,1,L.length);
  cout<<"经过快速排序后:"<<endl;
  OutPutSort(L);
}
 
int main() {
    // 初始化学生信息表
    SqList L;
    L.r[1].key = 87; L.r[1].otherinfo = "aaa";
    L.r[2].key = 76; L.r[2].otherinfo = "bbb";
    L.r[3].key = 92; L.r[3].otherinfo = "ccc";
    L.r[4].key = 64; L.r[4].otherinfo = "ddd";
    L.r[5].key = 55; L.r[5].otherinfo = "eee";
    L.r[6].key = 78; L.r[6].otherinfo = "fff";
    L.r[7].key = 100; L.r[7].otherinfo = "ggg";
    L.r[8].key = 43; L.r[8].otherinfo = "hhh";
    L.length = 8;
 
    cout << "原始学生信息表:";
    OutPutSort(L);
 
    // 不同排序算法进行排序
       
    InsetSort(L);
  BInsertSort (L);
    BubbleSort(L);
    SelectSort(L);
    int d[] = {5, 3, 1}; // 增量数组d
    ShellSort(L, d, 3);
    QuickSort(L);
 
    return 0;
}
相关文章
|
1月前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
23 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
1月前
|
存储 搜索推荐 算法
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
22 1
|
1月前
|
搜索推荐 索引
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理(二)
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理
|
1月前
|
搜索推荐 C++
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理(一)
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理
|
1月前
|
算法
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
05_用一个栈实现另一个栈的排序
05_用一个栈实现另一个栈的排序
|
1月前
|
人工智能 搜索推荐 算法
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理(三)
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理
|
3月前
|
C语言
数据结构——排序【上】
数据结构——排序【上】
|
3月前
|
搜索推荐 算法 测试技术
【数据结构】排序
【数据结构】排序
|
4月前
|
搜索推荐
【数据结构常见七大排序(三)上】—交换排序篇【冒泡排序】And【快速排序】
【数据结构常见七大排序(三)上】—交换排序篇【冒泡排序】And【快速排序】
【数据结构常见七大排序(三)上】—交换排序篇【冒泡排序】And【快速排序】

热门文章

最新文章