各种内部排序算法的测试

/* 各种内部排序算法的测试*/
#include <cstdio>
#include <cstdlib>
#include <ctime>

//辅助函数
/* 产生size以内的size个随机数放到array中 */
static void random_access(int array[], int size);
static void show_array(const int array[], int size);

/* 1. 直接插入排序 */
static void direct_insert_sort(int array[], int num)
{
    int i, j;

    for (i = 1; i <= num-1; ++i)
    {
        if (array[i] < array[i-1])
        {
            int tmp = array[i];
            for (j = i; j >= 1 && tmp < array[j-1]; --j)
            {
                array[j] = array[j-1];
            }
            array[j] = tmp;
        }
    }
}

/* SHELL排序, 是插入排序的演变, 有可变的步长 */
static void shell_sort(int array[], int num)
{
    int dk, i, j;
    int tmp;

    for (dk = num/2; dk >= 1; dk/=2)
    {
        for (i = dk; i <= num-1; ++i)
        {
            if (array[i] < array[i-dk])
            {
                tmp = array[i];
                for (j = i; j >= dk && array[j-dk] > tmp; j -= dk)
                {
                    array[j] = array[j-dk];
                }
                array[j] = tmp;
            }
        }
    }
}

/*堆排序 */
//堆中的元素下滤
static void down_filter(int array[], int num , int index)
{
    int i, child, tmp;

    for (i = index, tmp = array[i]; (i*2+1) <= num-1; i = child)
    {
        child = i*2+1;
        if (child != num -1 && array[child+1] > array[child])
            ++child;

        if (array[child] > tmp)
            array[i] = array[child];
        else
            break;
    }
    array[i] = tmp;

}
static void heap_sort(int array[], int num)
{
    int i;

    //建堆(max)
    for (i = num/2; i>=0; --i)
        down_filter(array, num, i);

    //每次删除最小元素
    for (i = num-1; i >=1; --i)
    {   /* 删除最小元素, 保存到最后位置, 结束时堆刚好从小到大排列 */
        int tmp = array[0];
        array[0] = array[i];
        array[i] = tmp;

        down_filter(array, i, 0); /*重新下滤第一位的元素 */
    }
}

/* 归并排序(递归) */
static void msort(int array[], int tmp_array[], int left, int right);
static void merge(int array[], int tmp_array[], int left_begin, int right_begin, int right_end);
static void merge_sort(int array[], int num)
{
    int *tmp_array = new int[num];
    if (tmp_array != NULL)
    {
        msort(array, tmp_array, 0, num-1);
        delete tmp_array; tmp_array = NULL;
    }
    return;
}
static void msort(int array[], int tmp_array[], int left, int right)
{
    if (left < right)//改组至少有另个元素
    {
        int mid = left + (right-left)/2;
        msort(array, tmp_array, left, mid);
        msort(array, tmp_array, mid+1, right);
        merge(array, tmp_array, left, mid+1, right);
    }
}
static void merge(int array[], int tmp_array[], int left_begin, int right_begin, int right_end)
{
    int left_end = right_begin - 1;
    int tmp_pos = left_begin;
    int num_elements = right_end - left_begin + 1;

    while (left_begin <= left_end && right_begin <= right_end)
    {
        if (array[left_begin] < array[right_begin])
            tmp_array[tmp_pos++] = array[left_begin++];
        else
            tmp_array[tmp_pos++] = array[right_begin++];
    }

    while (left_begin <= left_end)
        tmp_array[tmp_pos++] = array[left_begin++];
    while (right_begin <= right_end)
        tmp_array[tmp_pos++] = array[right_begin++];

    for (int i = 0; i < num_elements; ++i, right_end--)
        array[right_end] = tmp_array[right_end];
}


//修正后的快速排序, 大小为10左右的数据量用直接插入排序
static const int CUT_OFF = 10;
static void q_sort(int array[], int left, int right);
static int median3(int array[], int left, int right);
static void swap_int(int &a, int &b);
static void quick_sort(int array[], int num)
{
    q_sort(array, 0, num-1);
}

void q_sort(int array[], int left, int right)
{
    int i, j;
    int priovt;

    if (left > right ) return;

    if (left + CUT_OFF <= right)
    {
        i = left;
        j = right;
        priovt = median3(array, left, right); /* 选参照物[0, mid, right的中值] */

        while (i < j)
        {
            while (i<j && array[j] >= priovt)
                j--;
            array[i] = array[j];
            while (i<j && array[i] <= priovt)
                i++;
            array[j] = array[i];
        }
        array[i] = priovt;

        q_sort(array, left, i-1);
        q_sort(array, i+1, right);
    }
    else
    {
        direct_insert_sort(array+left, right-left+1);
    }
}

static int median3(int array[], int left, int right)
{
    int mid = left + (right - left)/2;

    /* make sure that: array[left] <= array[mid] <= array[right] */
    if (array[left] > array[mid])
    {
        swap_int(array[left], array[mid]);
    }
    if (array[left] > array[right])
    {
        swap_int(array[left], array[right]);
    }
    if (array[mid] > array[right])
    {
        swap_int(array[mid], array[right]);
    }

    swap_int(array[mid], array[left]);
    return array[left];
}

static void swap_int(int &a, int &b)
{
    int tmp;
    tmp = a;
    a = b;
    b = tmp;
}

static void random_access(int array[], int size)
{
    int i;

    if (array == NULL) return;

    srandom((unsigned)time(NULL));
    for (i = 0; i < size; ++i)
        array[i] = random()%size;
}

static void show_array(const int array[], int size)
{
    for (int i = 0; i < size; ++i)
        printf("%d ", array[i]);
    printf("\n");
}

int main(void)
{
    static const int MAX_ARRAY_SIZE = 30;
    int *pArray = new int[MAX_ARRAY_SIZE];
    random_access(pArray, MAX_ARRAY_SIZE);
    show_array(pArray, MAX_ARRAY_SIZE);
    printf("direct_insert_sort:\n");
    direct_insert_sort(pArray, MAX_ARRAY_SIZE);
    show_array(pArray, MAX_ARRAY_SIZE);

    printf("\n");
    random_access(pArray, MAX_ARRAY_SIZE);
    show_array(pArray, MAX_ARRAY_SIZE);
    printf("shell_sort:\n");
    shell_sort(pArray, MAX_ARRAY_SIZE);
    show_array(pArray, MAX_ARRAY_SIZE);

    printf("\n");
    random_access(pArray, MAX_ARRAY_SIZE);
    show_array(pArray, MAX_ARRAY_SIZE);
    printf("heap_sort:\n");
    heap_sort(pArray, MAX_ARRAY_SIZE);
    show_array(pArray, MAX_ARRAY_SIZE);

    printf("\n");
    random_access(pArray, MAX_ARRAY_SIZE);
    show_array(pArray, MAX_ARRAY_SIZE);
    printf("merge_sort:\n");
    merge_sort(pArray, MAX_ARRAY_SIZE);
    show_array(pArray, MAX_ARRAY_SIZE);

    printf("\n");
    random_access(pArray, MAX_ARRAY_SIZE);
    show_array(pArray, MAX_ARRAY_SIZE);
    printf("quick_sort:\n");
    quick_sort(pArray, MAX_ARRAY_SIZE);
    show_array(pArray, MAX_ARRAY_SIZE);
    delete []pArray; pArray = NULL;
    return 0;
}

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、付费专栏及课程。

余额充值