数据结构重读 – 队列 & 双端队列

队列(queue)是一种先进先出(FIFO)的线性表。只允许在一端进行插入,而在另一端删除元素。

允许插入的一端叫做队尾,允许删除的一端叫做队头。

双端队列(deque):限定插入和删除操作在表两端进行的线性表。

双端队列在一些限定条件下可以退化为:
(1)普通队列(只能在一端插入而另外一端删除)
(2)两个栈底相连的栈

队列 / 双端队列的定义:

由于可以在双端操作,所以肯定得有一个head,一个rear(tail)。我觉得确实用一个多的空头表示比较合适,然后头的data可以表示队列中有多少元素。

注意1:删除队列头时,如果被删除的元素是队列中最后一个元素时,一定要记得更新尾结点为NULL!

注意2:双端队列在队尾删除的时候,由于没有保存前向指针,需要从head从头遍历到tail的前一个,还要注意考虑只有一个结点的特殊情况。

代码如下:

 

#include <stdio.h>
#include <stdlib.h>

struct Node
{
	struct Node* next;
	int data;
};

struct Deque
{
	struct Node* head;
	struct Node* tail;
};

int deque_init(struct Deque* dq)
{
	dq->head = (struct Node*)malloc(sizeof(struct Node));
	if(!dq->head)
	{
		return -1;
	}
	dq->tail = (struct Node*)malloc(sizeof(struct Node));
	if(!dq->tail)
	{
		return -1;
	}
	dq->head->data = dq->tail->data = 0;
	dq->head->next = dq->tail->next = NULL;
	return 0;
}

void deque_print(struct Deque* dq)
{
	struct Node* ptr = dq->head;
	while(ptr->next!=NULL)
	{
		ptr = ptr->next;
		printf("%d ", ptr->data);
	}
	printf("\n");
}

int deque_length(struct Deque* dq)
{
	if(!dq->head)
	{
		return 0;
	}else
	{
		return dq->head->data;
	}
}

void deque_free(struct Deque* dq)
{
	struct Node* ptr = dq->head;
	struct Node* ptr2 = NULL;
	// Free all except tail
	while(ptr!=NULL)
	{
		ptr2 = ptr->next;
		free(ptr);
		ptr = ptr2;
	}
	// Free tail
	if(dq->tail)
	{
		free(dq->tail);
	}
	dq->head = dq->tail = NULL;
}

int deque_head_enqueue(struct Deque* dq, int data)
{
	struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
	if(!new_node)
	{
		return -1;
	}
	new_node->next = NULL;
	new_node->data = data;
	new_node->next = dq->head->next;
	dq->head->next = new_node;
	dq->head->data++;
	// If new node was also tail
	if(new_node->next==NULL)
	{
		dq->tail->next = new_node;
	}
}

int deque_head_dequeue(struct Deque* dq, int* data)
{
	struct Node* free_node = dq->head->next;
	if(free_node)
	{
		*data = free_node->data;
		dq->head->next = free_node->next;
		// If only one node
		if(free_node->next==NULL)
		{
			dq->tail->next = NULL;
		}
		free(free_node);
		dq->head->data--;
		return 0;
	}else
	{
		return -1;
	}
}

int deque_tail_enqueue(struct Deque* dq, int data)
{
	struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
	if(!new_node)
	{
		return -1;
	}
	new_node->data = data;
	new_node->next = NULL;
	dq->head->data++;
	// if list is empty
	if(dq->tail->next==NULL)
	{
		dq->head->next = new_node;
		dq->tail->next = new_node;
	} else
	{
		dq->tail->next->next = new_node;
		dq->tail->next = new_node;
	}
}

int deque_tail_dequeue(struct Deque* dq, int* data)
{
	struct Node* free_node = dq->tail->next;
	struct Node* ptr = NULL;
	if(!free_node)
	{
		return -1;
	}
	*data = free_node->data;
	// Find node
	ptr = dq->head;
	free_node = dq->tail->next;
	while(ptr->next!=free_node)
	{
		ptr = ptr->next;
	}
	// Only one node
	if(ptr==dq->head)
	{
		free(free_node);
		dq->head->next = dq->tail->next = NULL;
		dq->head->data = 0;
	}else
	{
		free(free_node);
		ptr->next = NULL;
		dq->tail->next = ptr;
		dq->head->data--;
	}
	return 0;
}

int deque_head(struct Deque* dq, int* data)
{
	struct Node* head = dq->head->next;
	if(head!=NULL)
	{
		*data = head->data;
		return 0;
	}else
	{
		return 1;
	}
}

int deque_tail(struct Deque* dq, int* data)
{
	struct Node* tail = dq->tail->next;
	if(tail!=NULL)
	{
		*data = tail->data;
		return 0;
	}else
	{
		return 1;
	}
}

int main()
{
	struct Deque dq;
	int i;
	int data;
	if(deque_init(&dq))
	{
		printf("deque init fail.\n");
		return -1;
	}
	//deque_head_enqueue(&dq, 888);
	//deque_tail_enqueue(&dq, 888);
	//deque_tail_dequeue(&dq, &data);
	// Head
	if(!deque_head(&dq, &data))
	{
		printf("Head:%d\n", data);
	}else
	{
		printf("Deque is empty, no head\n");
	}
	// Tail
	if(!deque_tail(&dq, &data))
	{
		printf("Tail:%d\n", data);
	}else
	{
		printf("Deque is empty, no tail\n");
	}
	// Length
	printf("Length:%d\n", deque_length(&dq));
	// Head Enqueue
	//for(i=0;i<10;i++)
	//{
	//	deque_head_enqueue(&dq, i);
	//}
	//for(i=0;i<8;i++)
	//{
	//	deque_head_dequeue(&dq, &data);
	//}
	// Tail Enqueue
	for(i=0;i<10;i++)
	{
		deque_tail_enqueue(&dq, i);
	}
	for(i=0;i<8;i++)
	{
		deque_tail_dequeue(&dq, &data);
	}
	deque_print(&dq);
	printf("Length:%d\n", deque_length(&dq));
	// Tail
	if(!deque_tail(&dq, &data))
	{
		printf("Tail:%d\n", data);
	}else
	{
		printf("Deque is empty, no tail\n");
	}
	deque_free(&dq);
	return 0;
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *