数据结构 实验六 排序

数据结构 实验六  排序

 

 

本次实验实现排序中的直接插入、冒泡排序、快速排序、简单选择排序、堆排序等排序算法。

 

下面放一下自己的代码:

 

#include <stdio.h>
#include <stdlib.h>
#include "DataHead.h"

#define MAXSIZE 20

typedef int KeyType;

typedef struct {
    KeyType key;
    //InfoType otherinfo;
}RedType;

typedef struct {
    RedType r[MAXSIZE+1];
    int length;
}SqList;

typedef SqList HeapType;    // 堆采用顺序表存储表示


void main()
{
    // 函数声明
    void CreateSqList(SqList &L);
    void ShowList(SqList L);
    void InsertSort(SqList &L);
    void QuickSort(SqList &L);
    void SelectSort(SqList &L);
    void HeapSort(HeapType &H);
    void BubbleSort(SqList &L);

    SqList L;

    printf("\n*********************** 排 序 ***********************\n\n");
    
    CreateSqList(L);    // 创建顺序表

    int selectIndex = 0;
    while(true)
    {
        printf("\n\n(1)、插入排序\n");
        printf("(2)、冒泡排序\n");
        printf("(3)、快速排序\n");
        printf("(4)、简单选择排序\n");
        printf("(5)、堆排序\n");
        printf("(6)、重新建立一个新的顺序表\n");
        printf("(0)、退出程序\n\n");
        printf("\n----------------------请选择您希望的操作序号:");
        scanf("%d", &selectIndex);
        switch(selectIndex)
        {
        case 1:
            InsertSort(L);
            ShowList(L);
            break;
        case 2:
            BubbleSort(L);
            ShowList(L);
            break;
        case 3:
            QuickSort(L);
            ShowList(L);
            break;
        case 4:
            SelectSort(L);
            ShowList(L);
            break;
        case 5:
            HeapSort(L);
            ShowList(L);
            break;
        case 6:
            CreateSqList(L);
            break;
        case 0:
            return;
        default:
            break;
        }
        printf("\n");
        system("pause");
    }


    system("pause");
}



bool EQ(KeyType a, KeyType b)    { return a == b; }
bool LT(KeyType a, KeyType b)    { return a < b; }
bool LQ(KeyType a, KeyType b)    { return a <= b; }

void CreateSqList(SqList &L)
{
    int length, i;
    printf("请构造一个任意的顺序表,以备接下来的排序所用: \n");
    printf("请输入顺序表的长度: \n");
    scanf("%d", &length);
    L.length = length;
    for(i = 1; i <= L.length; i++)
    {
        printf("请输入第 <%d> 个元素的值: ", i);
        scanf("%d", &L.r[i].key);
    }
    printf("\n\n顺序表创建完成!\n\n");
}

void ShowList(SqList L)
{
    int i;
    printf("排序后的顺序表为: \n");
    for(i = 1; i <= L.length; i++)
    {
        printf("%d  ", L.r[i].key);
    }
}

void InsertSort(SqList &L) {  // 算法10.1
  // 对顺序表L作直接插入排序。
  int i,j;
  for (i=2; i<=L.length; ++i)
    if (LT(L.r[i].key, L.r[i-1].key)) { 
      // "<"时,需将L.r[i]插入有序子表
      L.r[0] = L.r[i];                 // 复制为哨兵
      for (j=i-1;  LT(L.r[0].key, L.r[j].key);  --j)
        L.r[j+1] = L.r[j];             // 记录后移
      L.r[j+1] = L.r[0];               // 插入到正确位置
    }
} // InsertSort

int Partition(SqList &L, int low, int high) {  // 算法10.6(b) 快速排序
   // 交换顺序表L中子序列L.r[low..high]的记录,使枢轴记录到位,
   // 并返回其所在位置,此时,在它之前(后)的记录均不大(小)于它
   KeyType pivotkey;
   L.r[0] = L.r[low];            // 用子表的第一个记录作枢轴记录
   pivotkey = L.r[low].key;      // 枢轴记录关键字
   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;                   // 返回枢轴位置
} // Partition

//int Partition(SqList &L, int low, int high) {  // 算法10.6(a)
//   // 交换顺序表L中子序列L.r[low..high]的记录,使枢轴记录到位,
//   // 并返回其所在位置,此时,在它之前(后)的记录均不大(小)于它
//   KeyType pivotkey;
//   RedType temp;
//   pivotkey = L.r[low].key;     // 用子表的第一个记录作枢轴记录
//   while (low<high) {           // 从表的两端交替地向中间扫描
//      while (low<high && L.r[high].key>=pivotkey) --high;
//      temp=L.r[low];
//      L.r[low]=L.r[high];
//      L.r[high]=temp;           // 将比枢轴记录小的记录交换到低端
//      while (low<high && L.r[low].key<=pivotkey) ++low;
//      temp=L.r[low];
//      L.r[low]=L.r[high];
//      L.r[high]=temp;           // 将比枢轴记录大的记录交换到高端
//   }
//   return low;                  // 返回枢轴所在位置
//} // Partition

void QSort(SqList &L, int low, int high) {  //算法10.7
  // 对顺序表L中的子序列L.r[low..high]进行快速排序
  int pivotloc;
  if (low < high) {                      // 长度大于1
    pivotloc = Partition(L, low, high);  // 将L.r[low..high]一分为二
    QSort(L, low, pivotloc-1); // 对低子表递归排序,pivotloc是枢轴位置
    QSort(L, pivotloc+1, high);          // 对高子表递归排序
  }
} // Qsort

void QuickSort(SqList &L) {  // 算法10.8
   // 对顺序表L进行快速排序
   QSort(L, 1, L.length);
} // QuickSort

// 在L.r[i..L.length]中选择key最小的记录
int SelectMinKey(SqList L, int i)
{
    int k = i;
    int min = L.r[i].key;
    for( ; i <= L.length; i++ )
    {
        if(L.r[i].key < min)
        {
            min = L.r[i].key;
            k = i;
        }
    }
    return k;
}

void SelectSort(SqList &L) {  // 算法10.9
  // 对顺序表L作简单选择排序。
  int i,j;
  for (i=1; i<L.length; ++i) { // 选择第i小的记录,并交换到位
    j = SelectMinKey(L, i);  // 在L.r[i..L.length]中选择key最小的记录
    if (i!=j) {                // L.r[i]←→L.r[j];   与第i个记录交换
      RedType temp;
      temp=L.r[i];
      L.r[i]=L.r[j];
      L.r[j]=temp;    
    } 
  }
} // SelectSort

void HeapAdjust(HeapType &H, int s, int m) {  // 算法10.10
  // 已知H.r[s..m]中记录的关键字除H.r[s].key之外均满足堆的定义,
  // 本函数调整H.r[s]的关键字,使H.r[s..m]成为一个大顶堆
  // (对其中记录的关键字而言)
  int j;
  RedType rc;
  rc = H.r[s];
  for (j=2*s; j<=m; j*=2) {   // 沿key较大的孩子结点向下筛选
    if (j<m && H.r[j].key<H.r[j+1].key) ++j; // j为key较大的记录的下标
    if (rc.key >= H.r[j].key) break;         // rc应插入在位置s上
    H.r[s] = H.r[j];  s = j;
  }
  H.r[s] = rc;  // 插入
} // HeapAdjust

void HeapSort(HeapType &H) {  // 算法10.11
   // 对顺序表H进行堆排序。
   int i;
   RedType temp;
   for (i=H.length/2; i>0; --i)  // 把H.r[1..H.length]建成大顶堆
      HeapAdjust ( H, i, H.length );
      for (i=H.length; i>1; --i) {
         temp=H.r[i];
         H.r[i]=H.r[1];
         H.r[1]=temp;  // 将堆顶记录和当前未经排序子序列Hr[1..i]中
                       // 最后一个记录相互交换
         HeapAdjust(H, 1, i-1);  // 将H.r[1..i-1] 重新调整为大顶堆
      }
} // HeapSort

// 冒泡排序
void BubbleSort(SqList &L)
{
    int i, j, temp;
    bool change = TRUE;
    for( i = L.length; i >= 1 && change; --i )
    {
        change = FALSE;
        for( j =0; j < i; ++j )
        {
            if( L.r[j].key > L.r[j+1].key )
            {
                temp = L.r[j].key;
                L.r[j].key = L.r[j+1].key;
                L.r[j+1].key = temp;
                change = TRUE;
            }
        }
    }
}// Bubble_Sort

 

 

可以直接复制上述代码,也可以去我的网盘下载源cpp文件

http://pan.baidu.com/s/105Jqr

 

 

 

 

 

转载于:https://www.cnblogs.com/uppercloud/p/DataStructure_Sort.html

1.实验目的 掌握内排序,比较各种排序的优、缺点。 2 需求分析 2.1原理 2.1.1、直接排序 算法描述:经过i-1遍处理后,L[1..i-1]己排好序。第i遍处理仅将L[i]插入L[1..i-1]的适当位置,使得L[1..i]又是排好序的序列。要达到这个目的,我们可以用顺序比较的方法。首先比较L[i]和L[i-1],如果L[i-1]≤ L[i],则L[1..i]已排好序,第i遍处理就结束了;否则交换L[i]与L[i-1]的位置,继续比较L[i-1]和L[i-2],直到找到某一个位置j(1≤j≤i-1),使得L[j] ≤L[j+1]时为止。 2.1.2、冒泡排序 算法描述:核心思想是扫描数据清单,寻找出现乱序的两个相邻的项目。当找到这两个项目后,交换项目的位置然后继续扫描。重复上面的操作直到所有的项目都按顺序排好。 2.1.3、快速排序 算法描述:首先检查数据列表中的数据数,如果小于两个,则直接退出程序。如果有超过两个以上的数据,就选择一个分割点将数据分成两个部分,小于分割点的数据放在一组,其余的放在另一组,然后分别对两组数据排序。通常分割点的数据是随机选取的。这样无论你的数据是否已被排列过,你所分割成的两个字列表的大小是差不多的。而只要两个子列表的大小差不多。 2.1.4、选择排序 算法描述:首先找到数据清单中的最小的数据,然后将这个数据同第一个数据交换位置;接下来找第二小的数据,再将其同第二个数据交换位置,以此类推。 2.1.5、堆排序 (1) 基本思想:堆排序是一树形选择排序,在排序过程中,将R[1..N]看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择最小的元素。 (2) 堆的定义: N个元素的序列K1,K2,K3,...,Kn.称为堆,当且仅当该序列满足特性: Ki≤K2i Ki ≤K2i+1(1≤ I≤ [N/2]) 2.1.6、希尔排序 算法描述:在直接插入排序算法中,每次插入一个数,使有序序列只增加1个节点,并且对插入下一个数没有提供任何帮助。如果比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除多个元素交换。 2.2要求 1.本程序对以下六种常用内部排序算法进行实测比较:冒泡排序,插入排序,选择排序,希尔排序,快速排序,堆排序。 2.排序的元素的关键字为整数。用正序,逆序,不同乱序的数据作测试比较。比较的指标为有关键字参加的比较次数和关键字的移动次数。 3.程序以人机对话的形式进行,每次测试完毕显示各种比较指标值 。 2.3任务 设计一个测试程序比较几种内部排序算法的关键字比较次数和移动次数以取得直观感受。 2.4运行环境 (1)WINDOWSXP系统 (2)C++ 编译环境 3.实验方法 本实验主要是内排序,通过比较的次数和移动的次数判断排序的好坏。主要子函数的说明如下。 1.简单选择排序XuanzePaixu(); 2.冒泡排序MaopaoPaixu(); 3. 直接插入排序CharuPaixu(); 4. 快速排序KuaisuPaixu(); 5. 堆排序DuiPaixu(); 6. 希尔排序 XierPaixu(); 以上的排序算法均采用书中所用的算法。程序采用输入的时候仅输入所要的个数,具体的输入数据由程序随机产生个数,并且输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值