根据邓老师的讲解,实现Javis March算法计算凸包,但是时间复杂度并没有直接降低,在最坏的情况下还是O(n^2).
实际上,该算法是在极边法上的改进,降低算法寻找边的复杂度..
具体的计算过程如下描述.
#include <iostream>
#include <vector>
using namespace std;
struct point
{
point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
int x;
int y;
};
enum Loc
{
left,
online,
right
};
struct node
{
node(point _p) : p(_p), next(nullptr), prev(nullptr) {}
point p;
node *prev;
node *next;
};
int Area(point p, point q, point s)
{
return p.x * q.y - p.y * q.x +
q.x * s.y - q.y * s.x +
s.x * p.y - s.y * p.x;
}
Loc ToLeft(point p, point q, point s)
{
auto area = Area(p, q, s);
if (area > 0)
return Loc::left;
if (area == 0)
return Loc::online;
if (area < 0)
return Loc::right;
}
int Ltl(vector<point> points)
{
int ltl = 0;
for (int i = 0; i < points.size(); ++i)
{
if (points[i].y < points[ltl].y || (points[i].y == points[ltl].y && points[i].x < points[ltl].x))
ltl = i;
}
return ltl;
}
int main()
{
vector<point> points = {
{1, 1},
{2, 2},
{2, 0},
{2, 4},
{3, 3},
{4, 2}
};
vector<bool> flag(points.size(), false);
int ltl = Ltl(points);
vector<point> res;
int k = ltl;
do
{
res.push_back(points[k]);
int s = -1;
for (int i = 0; i < points.size(); ++i)
{
if (i != k && i != s &&
(s == -1 || ToLeft(points[k], points[s], points[i]) != Loc::left)
&& (flag[i] == false))
s = i;
}
k = s;
flag[k] = true;
} while (k != ltl);
for(auto p: res)
cout << p.x << " " << p.y << endl;
return 0;
}