拉格朗日插值、牛顿插值、分段线性内插算法 如何体现节点选择过程?


#include <iostream>
#include <vector>
#include <fstream>
using namespace std;

double Lagrange(int N, vector<double>& x, vector<double>& y, double X)//拉格朗日插值法
{
    double result = 0;
    for (int k = 0; k < N; k++)
    {
        double t = y[k];
        for (int i = 0; i < N; i++)
        {
            if (i != k) {
                t *= (X - x[i]);
                t /= (x[k] - x[i]);
            }
        }
        result += t;
    }
    return result;
}

double Quotient(int N, vector<double>& x, vector<double>& y)//差商
{
    double f = 0;
    double t = 0;
    for (int i = 0; i <= N; i++)
    {
        t = y[i];
        for (int j = 0; j <= N; j++)
        {
            if (i != j) t /= (x[i] - x[j]);
        }
        f += t;
    }
    return f;
}
double Newton(int N, vector<double>& x, vector<double>& y, double X)//牛顿插值法
{
    double result = 0;
    for (int i = 0; i < N; i++)
    {
        double t = 1;
        double f = Quotient(i, x, y);
        for (int j = 0; j < i; j++)
        {
            t = t * (X - x[j]);
        }
        result += f * t;
    }
    return result;
}

double lineLag(int N, vector<double>& x, vector<double>& y, double X)//分段线性插值法
{
    double m1, m2, t1, t2;
    vector<double>temp(N);
    int n = 0;
    m1 = X;
    for (int i = 0; i < N - 1; i++)//冒泡排序法
    {
        for (int j = 0; j < N - 1 - i; j++)
        {
            if (x[j] > x[j + 1]) {
                t1 = x[j];//x进行升序排序
                x[j] = x[j + 1];
                x[j + 1] = t1;
                t2 = y[j];//对应的y值跟着变位置
                y[j] = y[j + 1];
                y[j + 1] = t2;
            }
        }
    }
    //找最近点
    for (int i = 0; i < N; i++)
    {
        if (x[i] < X)//先找到区间左值
        {
            m1 = x[i];
            n = i + 1;
        }
    }
    if (X == m1 + 1) m2 = m1 + 2;//右值
    else m2 = m1 + 1;
    double result = y[n - 1] * ((X - m2) / (m1 - m2)) + y[n] * ((X - m1) / (m2 - m1));
    return result;
}

int main(void)
{
    int N;
    double x;
    double result;

    ifstream infile;
    infile.open("数据.txt", iostream::in);
    if (!infile.is_open())//文件不存在
    {
        cout << "Open file failure!" << endl;
    }
    
    infile >> N;//先读取第一行
    vector<double>X(N);
    vector<double>Y(N);
    for (int i = 0; i < N; i++)
    {
        infile >> X[i] >> Y[i];
    }
    cout << "输入需要计算的x值:";
    cin >> x;
    cout << "拉格朗日插值法计算结果为:" << Lagrange(N, X, Y, x) << endl;
    cout << "牛顿插值法计算结果为:" << Newton(N, X, Y, x) << endl;
    cout << "分段线性插值法计算结果为:" << lineLag(N, X, Y, x) << endl;
    infile.close();

    return 0;
}