#include <stdio.h>
#include "as.h"
#include "misc.h"

#if !defined(lint) && !defined(SABER)
static	char	sccsid[] = "@(#)as_merge.c	1.2	11/13/90";
#endif /* not lint */

extern	s_char *calloc();

/*
 * Merge neighbors into queue, keeping it sorted.  "neighbors" is sorted,
 * both by lower bound cost and then by secondary cost.
 */
struct as_queue *
as_merge(adp, head, neighbors)
	struct as_data	*adp;
	struct as_queue	*head;
	struct as_node	**neighbors;
{
	struct as_queue	*qp;
	struct as_queue	*pp;		/* previous pointer */
	struct as_queue	*ip;		/* insert pointer */
	struct as_node	*np;
	int		i;

	qp = head;
	pp = NULL;
	for (i = 0; neighbors[i]; i++) {
		np = neighbors[i];
		/* scan until qp points to a node we should go in front of */
		while (qp && (qp->np->lbcost < np->lbcost)) {
			pp = qp;
			qp = qp->next;
		}
		/* check for equal lower bounds, and use secondary cost if = */
		if (qp && qp->np->lbcost == np->lbcost) {
			while (qp && (qp->np->lbcost == np->lbcost) &&
				(qp->np->seccost < np->seccost)) {
				pp = qp;
				qp = qp->next;
			}
		}
		AS_NEW(ip, struct as_queue, NULL);
		/* if there was such a node, insert us in front of it */
		if (qp) {
			ip->prev = qp->prev;
			if (ip->prev)
				ip->prev->next = ip;
			ip->next = qp;
			qp->prev = ip;
			if (qp == head)
				head = ip;
		} else {	/* otherwise add us to end of queue */
			ip->prev = pp;
			if (ip->prev)
				ip->prev->next = ip;
			else {
				head = ip;
			}
			pp = ip;
		}
		ip->np = np;
		as_setcinq(adp, np->c, ip);
		np->step++;
	}

	return (head);
}
