关于优先级队列的

参照贺宏宏老师给的写的。
顺序的和链式的。每种的又分为“无序入(正常的尾入),有序出”和“有序入,无序出(正常的头出)”。思想都很简单,没什么说的。下面只说代码实现。
顺序的比较简单,没什么说的。
就是链式的比较麻烦,第一次写,真是有些麻烦(其实不难,就是没做好心理准备,觉得链式的应该跟顺序的一样很简单)。
链式的麻烦在于:
1、链表的插入和删除,都需要先找到它的前一个,这样才能"真正的"插入和删除。但链式队列又是用专门的指针指向它的头尾的,也就是没头节点,这样的话,那个fri节点找起来就有些麻烦了。
2、链式队列的判空是判断front指针是否为NULL,以及链式队列的摧毁有个判断是判断front跟rear是否相等。那么也就需要保持尾节点的next必须为NULL,并且如果节点为空时,得保持front跟rear都为NULL。

所以上两个比较长的函数的代码,一个是"队列元素为无序状态"的有序出,一个是"队列元素为有序状态"的有序入。


"队列元素为无序状态"的有序出
//获取队头的值,且删除队头
bool PopDisorder(PPriIQueue pq, int *rtval)
{
	if (IsEmpty(pq) || rtval == NULL)//排除空
	{
		return false;
	}

	if (pq->front == pq->rear)//排除只有一个节点
	{
		*rtval = pq->front->data;

		free(pq->front);
		pq->front = NULL;
		pq->rear = NULL;

		return true;
	}
	
	//下面的都是至少有两个节点,所以肯定会有个fri

	//先将第一个节点当作"头节点"用,得到除过第一个节点外的优先级最高的那个节点的前一个节点的地址
	QNode *min_fri = pq->front;
	for (QNode *i = pq->front; i != pq->rear; i = i->next)
	{
		if (i->next->priority < min_fri->next->priority)
		{
			min_fri = i;
		}
	}

	if (pq->front->priority < min_fri->next->priority)//把上面的得到的优先级最高的节点跟第一个节点比较下
	{
		*rtval = pq->front->data;

		QNode *p = pq->front;
		pq->front = p->next;
		free(p);

		return true;
	}

	if (min_fri->next == pq->rear)//如果优先级最高的是尾节点,那就需要更新rear的指向
	{
		pq->rear = min_fri;
	}

	//下面是正式的删除
	*rtval = min_fri->next->data;

	QNode *p = min_fri->next;
	min_fri->next = p->next;
	free(p);

	return true;
}


"队列元素为有序状态"的有序入
//有序入队
bool PushOrder(PPriIQueue pq, int val, int priority)//将此新来的节点插在比它的优先级"大"(是大,不是小,也不是等于)的那个节点前面
{
	QNode *p = (QNode *)malloc(sizeof(QNode));
	p->data = val;
	p->priority = priority;

	if (IsEmpty(pq))//排除队列为空时
	{
		pq->front = p;
		pq->rear = p;
		pq->rear->next = NULL;

		return true;
	}
	if (pq->front == pq->rear)//排除只有一个节点
	{
		if (pq->front->priority > p->priority)//需要严格得按照规则来。先比较当前节点是否大于需要插入的节点的优先级!
		{
			p->next = pq->front;
			pq->front = p;

			return true;
		}
		else
		{
			pq->rear->next = p;
			pq->rear = p;
			pq->rear->next = NULL;

			return true;
		}
	}

	//下面队列至少有两个节点,所以肯定有fri

	if (pq->front->priority > p->priority)//排除插在第一个节点前面的情况
	{
		p->next = pq->front;
		pq->front = p;

		return true;
	}

	QNode *pos_fri;
	for (pos_fri = pq->front; pos_fri != pq->rear; pos_fri = pos_fri->next)
	{
		if (pos_fri->next->priority > p->priority)
		{
			break;
		}
	}

	if (pos_fri == pq->rear)
	{
		pq->rear->next = p;
		pq->rear = p;
		pq->rear->next = NULL;

		return true;
	}
	else
	{
		p->next = pos_fri->next;
		pos_fri->next = p;

		return true;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值