C++:选择排序

直接选择排序
#include <bits/stdc++.h>
using namespace std;


// 以从小到大排序为例
template<class T>
void SelectSort(T A[], int n)
{
    int i, j, k;
    T temp;
    for (i = 0; i < n - 1; i++) // 从左往右依次选出未确定区间最小值
    {
        k = i; // 首次默认当前位置数据为最小值
        for (j = i + 1; j < n; j++) // 依次将当前位置的数据与之后的数据比较
        {
            if (A[j].key < A[k].key) // 如果找到更小值则进行更新最小位置
            {
                k = j;
            }
        }
        if (i != k) // 如果最小位置发生更新则将当前位置的数据与最小位置的数据互换
        {
            temp = A[k]; A[k] = A[i]; A[i] = temp;
        }
    }
}


int main()
{
    int len;
    cin >> len;
    int * a = new int[len];
    for (int i = 0; i < len; i++)
    {
        cin >> a[i];
    }
    SelectSort(a, 10);
    
    for (int i = 0; i < len; i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;
    delete a;    

    return 0;
}
 
/*
测试
10
2 8 6 7 5 4 3 1 0 9
*/
树形选择排序
#include<bits/stdc++.h>
using namespace std;

#define Left(i)      (2*(i)-2*n) // 获取左子节点序号
#define Right(i)   (2*(i)-2*n+1) // 获取右子节点序号
#define Father(i)  (n+(i)/2) // 获取父节点序号
//#define Brother(i)  ((i)&1?(i)-1:(i)+1) // 
#define Root          (2*n-2) // 计算根节点序号
#define min(a,b)      (a)<(b)?(a):(b)
#define INF_VALUE  0x3FFFFFFF // 定义无穷大

//树形排序:从小到大
template<class T>
void TreeSort(T* a, int n) // n 为叶子结点个数
{
    T* t = new T(2 * n - 1); // 为二叉树分配空间
    memcpy(t, a, sizeof(T)*n); // 拷贝需要排序的数组,预置结果空间
 
    //第1轮选择
    for(int i = n; i <= Root; i++)
    {
        // 从第一个非叶子节点进行数值的确定,为两个子节点中数据的最小值
        t[i] = min(t[Left(i)], t[Right(i)]); 
    }
     a[0] = t[Root]; // 通过数值确定,根节点的数值即为最小值,存入结果空间第一位

     //第2轮至第n轮选择
     for(int k = 1; k <= n-1; k++) // 依次选择出第0号之后的最小数据
     {   
         // 将上一轮的最小值修改为无穷大INF_VALUE。
         // 沿着等于t[Root]的分枝向下直到叶节点t[sel]=t[Root]
         
          int sel = Root; // sel为储存已经找到的最小节点序号的临时变量
          int left = Left(sel); // 计算sel节点的左节点序号
          while(left >= 0) // 判断sel是否为叶节点
          {   
            sel = (t[sel] == t[left]) ? left : (left + 1); // sel从根往叶更新
               left = Left(sel);
          } 
          t[sel] = INF_VALUE; // 将上一轮的最小值修改为无穷大INF_VALUE
  
          // 本轮选择:从叶往根从t[sel]往t[Root]选择最小值
          
          // 由于只有当前sel的值发生改变,只需循着含有sel的节点的分支重新比较选择
          sel = Father(sel); // sel作为确定父节点数值的临时位置
          while(sel <= Root) // 依次选择出最小的新根节点数值
          {   
            t[sel] = min(t[Left(sel)], t[Right(sel)]);
               sel = Father(sel);
          }
          a[k] = t[Root]; // 更新结果空间中的数值
     }
     delete(t);
}

int main()
{
    int len;
    cin >> len;
    int * a = new int[len];
    for (int i = 0; i < len; i++)
    {
        cin >> a[i];
    }
    TreeSort(a, 10);
    
    for (int i = 0; i < len; i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;

    delete a;    

    return 0;
}
 
/*
测试
10
2 8 6 7 5 4 3 1 0 9
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值