C++改进的选择算法SELECT2

余祥宣, 崔国华, 邹海明. 计算机算法基础.3版[M]. 华中科技大学出版社, 2006.
P96 算法4.17

#include<iostream>
#include<time.h>
#include<windows.h>
using namespace std;

const int r=5;//步长

void InterChange(int&a, int&b)
{
    int temp = a;
    a = b;
    b = temp;
}

void InsertionSort(int A[], int start, int end)
{
    for (int j = start + 1; j <= end; j++)
    {
        int item = A[j];
        int i = j - 1;
        while (i>=start&&item < A[i])
        {
            A[i + 1] = A[i];
            i--;
        }
        A[i + 1]  = item;
    }
}

int Partition(int A[], int m, int p)//A[p+1]=无穷大
{
    int i, v;
    v = A[m];
    i = m;
    while (true)
    {
        do
        {
            i = i + 1;
        } while (A[i] < v);

        do
        {
            p = p - 1;
        } while (A[p] > v);

        if (i < p)
        {
            InterChange(A[i], A[p]);
        }
        else
        {
            break;
        }
    }
    A[m] = A[p];
    A[p] = v;
    return p;
}

void ShowList(int A[], int length=12)
{
    for (int i = 0; i<length; i++)
        cout << i << "=>" << A[i] << "\t";
    cout << endl;
}

int SEL(int A[],int m,int p,int k)
{
    int n, i, j;

    while (true)
    {
        n = p - m + 1;

        if (p - m + 1 <= r)
        {
            InsertionSort(A, m, p);
            return m + k - 1;
        }

        int nr_down = n / r;// n/r向下取整

        for (i = 1; i <= nr_down; i++)
        {
            InsertionSort(A, m + (i - 1)*r, m + i*r - 1);
            InterChange(A[m + i - 1], A[m + (i - 1)*r + (r + 2 - 1) / 2 - 1]);//中间值应该是r/2向上取整
        }

        //向上取整(a+b-1)/b
        //A[m,m+1,……,m+nr_down - 1]取中值即长度/2向上取整
        j = SEL(A, m, m + nr_down - 1, (nr_down + 2 - 1) / 2);

        //使用Partition(A,m,j)要做出调整
        InterChange(A[m], A[j]);
        j = p + 1;
        int temp = A[p + 1];
        A[j] = INT_MAX;
        j=Partition(A,m,j);
        A[p + 1] = temp; 

        if (j - m + 1 == k)
        { 
            return j;
        }           
        else if (j - m + 1 > k)
            p = j - 1;
        else
        {
            k = k - (j - m + 1);
            m = j + 1;
        }

    }
}

int main()
{
    const int len = 10;//数据量
    int a[len];
    int b[len];
    srand((unsigned)time(NULL));
    for (int i = 0; i < len; i++)
        a[i]=b[i] = rand()%100000+1;

    DWORD start, end;

    int index = rand() % len+ 1;//索引位置
    int key = 0;

    start = GetTickCount();
    key = SEL(a, 0, len-1,index);
    start = GetTickCount();
    cout << "Time:" << end - start << endl;

    ShowList(a, len);
    cout << endl <<" a["<<key<<"]"<<a[key]<<endl;

    start = GetTickCount();
    InsertionSort(b, 0, len - 1);
    start = GetTickCount();
    cout << "Time:" << end - start << endl;

    ShowList(b, len);
    cout << endl << " b[" << index-1 << "]" << a[index-1];

    system("pause");
    return 0;
}

运行结果
C++改进的选择算法SELECT2运行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值