KNN算法---求前K个数据。

简介

K Nearest Neighbor算法又叫KNN算法,K最近邻算法。K表示距离自己最近的k个数据样本。
个人觉得重点在距离如何表示,如何计算,是简单的用距离公式,还是用复杂的加权计算。最后都会输出
一个距离值。剩下的问题就可以抽象成一个求前K个数据。

代码
#include <vector>
#include <iostream>
using namespace std;
void adjust_heap(vector<int> & vec, int length, int i);
void gen_max_heap(vector<int> & vec);
void get_kmax_value(vector<int> &vec, vector<int> &kvec, int k);

int main()
{
    vector<int> vec = { 0, 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 };//第一位不用
    gen_max_heap(vec);
    vector<int> kvec;
    get_kmax_value(vec,kvec, 5);
    for (auto x : kvec)
        cout << x << endl;
    cin.get();
    return 0;
}
void adjust_heap(vector<int> & vec, int length, int root)
{
    int left    = 2 * i;
    int right   = 2 * i + 1;
    int largest = root;
    while (left < length || right < length)
    {
        if (left < length && vec[left] > vec[largest])
            largest = left;
        if (right < length && vec[right] > vec[largest])
            largest = right;
        if (i != largest)//继续调整被影响的子树
        {
            swap(vec[largest], vec[i]);
            root = largest;
            left    = 2 * root;
            right   = 2 * root + 1;
        }
        else
        {
            break;
        }
    }
}
void gen_max_heap(vector<int> & vec)
{
    int length = vec.size();
    for (auto root = (vec.size() - 1) / 2; root != 0; root--)
    {
        adjust_heap(vec, length, root);
    }
}
void get_kmax_value(vector<int> &vec, vector<int> &kvec, int k)
{
    int length = vec.size();
    for (int i = 0; i != k; ++i)
    {
        kvec.push_back(vec[1]);
        swap(vec[1], vec[length - 1 - i]);
        adjust_heap(vec, length - 1 - i, 1);
    }
}
//请使用支持c++11的编译器编译
分析
  1. 求前k个数据,常用的方法利用max_heap(大根堆)。
    简介大根堆,一棵完全二叉树,每个节点值都大于其子节点的值。
  2. 本人代码写的比较渣,在选择数据结构的时候选择了vector,在用的时候下标这个点很头疼。
    父子节点的下标问题:
    2.1 vec[0]元素不用。下标从1开始到n,子节点n,父节点[n/2]对应实现。
    2.2 下标与循环变量的选择。
  3. 核心在这个adjust_heap的操作
    如何构建大根堆,首先从最小的子树开始,本来应该是叶子节点。但是一个节点也没必要比较。
    那就从一个root和一层孩子的节点子树开始。这样的子树很简单就可以调整成root值大于孩子节点。
    关键是从3层的子树结构开始。由root和两个分别已经调整后的2层子树组成的子树。若root和两个孩子
    有所调整,那将影响调整的孩子的子树,那么将继续调整被影响的子树。无需调整的话,由于两个孩子也是已经调整好的,所以整个子树也不需要调整,break即可。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值