[GIS算法] 求单调链 - C语言实现

版权声明:本文为博主原创文章,若有错误之处望大家批评指正!转载需附上原文链接,谢谢! https://blog.csdn.net/summer_dew/article/details/83994079

单调链:一个点序列在某个直线上投影如果是有序的,则认为此点序相对与该直线是一个单调链

【问题】找到任意点序列相对于Y轴的所有单调链

在这里插入图片描述

#include<stdio.h>

typedef struct _POINT{
	double x;
	double y;
}POINT;

// 求单调链
int GetLink(POINT *points, int n) { //两个两个判断
	int i;
	int cnt=0;
	int start;
	int up=0; //不增不减

	start = 0; //起始点
	for (i=1; i<n; i++) {
		if (points[i-1].y < points[i].y) { //后一个y > 前一个y --> up
			if (up==-1) { //原来是-1,那就是转折点
				cnt++;
				printf("%d->%d down\n", start, i-1);
				start=i-1;
			}
			up = 1;
		} else if (points[i-1].y > points[i].y ) {
			if (up==1) {
				cnt++;
				printf("%d->%d up\n", start, i-1);
				start=i-1;
			}
			up = -1;
		}
		if (i==n-1) { //△ 最后一个点(很容易漏掉)
			printf("%d->%d %s\n", start, i, up==1?"up":"down");
			cnt++;
		}
	}

	return cnt;
}

int GetLink2(POINT *points, int n) { //三个三个判断
	int cnt=0;
	int i,start;
	
	if (n==2) { //只有两个点
		printf("%d->%d %s\n", 0, 1, points[0].y>points[1].y?"down":"up" );
		cnt++;
	} else {
		start = 0;
		for (i=1; i<n-1; i++) {
			//左边右边方向不一样,即为转折
			if ( (points[i].y-points[i-1].y)*(points[i+1].y-points[i].y)<0 ) {
				printf("%d->%d %s\n", start, i, points[i].y>points[i-1].y?"up":"down");
				start = i;
				cnt++;
			}
		}
		//△ 最后一个点(很容易漏掉)
		printf("%d->%d %s\n", start, n-1, points[n-1].y>points[n-2].y?"up":"down");
		cnt++;
	}
	return cnt;
}
/*
12
120.49357 44.883323
117.9872 42.350326
115.545833 39.79259
113.508521 38.274465
110.551524 37.151942
105.640902 39.126654
106.005868 38.125725
107.545122 34.951701
110.411982 31.777678
113.019257 28.194103
116.535467 26.871059
117.470083 23.943192
*/
int main() {
	int n;
	POINT points[100];
	int i;

	scanf("%d", &n);
	for (i=0; i<n; i++)
		scanf("%lf%lf", &points[i].x, &points[i].y);

	i = GetLink(points, n);
	printf("共找到%d\n", i);

	i = GetLink2(points, n);
	printf("共找到%d\n", i);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/summer_dew/article/details/83994079