1. 程式人生 > >資料結構中佇列的實現(基於順序表迴圈佇列)

資料結構中佇列的實現(基於順序表迴圈佇列)

    在學習資料結構中,佇列也是一個重要的資料結構,我們今天來用基於順序表的佇列(Queue),

在基於順序表佇列如果是不迴圈的順序表,則在出佇列時,時間複雜度是O(n),所以我們用迴圈佇列來

實現,怎麼解釋基於迴圈順序表的佇列呢?

我們上圖:

 

上圖是在不迴圈順序表中出隊。這樣不難看出時間複雜度不是很好。

所以我們來順序迴圈佇列,把順序表讓它迴圈利用。

看圖


上圖就是順序表迴圈佇列,a就是隊首,d就是隊尾,這樣可以避免出隊後移位,所以就時間複雜度更小。

那麼咱們來看程式碼:

先是宣告:

#pragma once

#include<stdio.h>
#define MAXREPOSITORY 10

#define TEAM_HEAD printf("\n===========%s==========\n",__FUNCTION__)

typedef char QueueType;

typedef struct SeqQueue{
	size_t count;
	size_t size;
	QueueType data[MAXREPOSITORY];
}SeqQueue;

// 初始化。
void InitSeqQueue(SeqQueue *seq);

// 入隊。
void PushQueue(SeqQueue *seq,QueueType value);

// 出隊。
void PopQueue(SeqQueue *seq);

// 取隊首元素。
QueueType FindHead(SeqQueue *seq);

// 取隊尾元素。
QueueType FindBottom(SeqQueue *seq);

// 銷燬。
void DestoryQueue(SeqQueue *seq);

看定義:

#include"SeqQueue.h"


// 初始化。
void InitSeqQueue(SeqQueue *seq)
{
	if (seq == NULL)
	{
		return;
	}
	seq->size = 0;
	seq->count = 0;
}


// 入隊。
void PushQueue(SeqQueue *seq,QueueType value)
{
	if (seq == NULL)
	{
		return;
	}
	if (seq->count == MAXREPOSITORY)
	{
		// 佇列滿。
		return;
	}
	// 當迴圈順序隊迴圈完但隊未滿時,進行迴圈。
	if (seq->size > MAXREPOSITORY) 
	{
		seq->size = 0;
	}
	seq->data[seq->size] = value;
	++seq->size;
	++seq->count;
}

// 出隊。
void PopQueue(SeqQueue *seq)
{
	if (seq == NULL)
	{
		return;
	}
	if (seq->count == 0)
	{
		// 空佇列。
		return;
	}
	--seq->count;
}


// 取隊尾元素。
QueueType FindButtom(SeqQueue *seq)
{
	if (seq == NULL)
	{
		printf("輸入錯誤\n");
		return 0;
	}
	if (seq->count == 0)
	{
		printf("隊為空\n");
		return 0;
	}
	return seq->data[seq->size-1];
}


// 取隊首元素。
QueueType FindHead(SeqQueue *seq)
{
	if (seq == NULL)
	{
		printf("輸入錯誤\n");
		return 0;
	}
	if (seq->count == 0)
	{
		printf("隊為空\n");
		return 0;
	}
	if (seq->size >= seq->count)
	{
		return seq->data[seq->size - seq->count];
	}
	else 
	{
		size_t tmp = seq->count-seq->size;
		size_t size = MAXREPOSITORY;
		return seq->data[size-tmp];
	}
}


// 銷燬。
void DestoryQueue(SeqQueue *seq)
{
	if (seq == NULL)
	{
		return;
	}
	seq->size = 0;
	seq->count = 0;
}

////////////////
//以下為測試程式碼
////////////////

void PrintSeqQueue(SeqQueue *seq)
{
	if (seq == NULL)
	{
		return;
	}
	printf("[隊尾]->");
	size_t count = 0;
	size_t size = seq->size;
	if (size != 0)
	{
		while (seq->count > count)
		{
			printf("[%c]->",seq->data[size-count-1]);
			count++;
		}
//		for (; count < seq->count; ++count)
//		{
//			printf("[%c]<-",seq->data[count]);
//		}
	}
	else
	{
		while (seq->count > count)
		{
			// 當迴圈到最大size但是隊未滿。
			if (size - count - 1 == 0)
			{
				printf("[%c]->",seq->data[size-count-1]);
				size = MAXREPOSITORY;
				count++;
			}
			else
			{
				printf("[%c]->",seq->data[size-count-1]);
				count++;
			}
		}
//		for(; count < seq->count; ++count)
//		{
//			if (size-count == 0)
//			{
//				size = MAXREPOSITORY;
//			}
//			printf("[%c]<-",seq->data[size-count]);
//		}
	}
	printf("[隊頭]\n");
}


// 順序隊的初始化。
void TestInitSeqQueue()
{
	TEAM_HEAD;
	SeqQueue seq;
	InitSeqQueue(&seq);
}

void TestPushQueue()
{
	TEAM_HEAD;
	SeqQueue seq;
	InitSeqQueue(&seq);
	PushQueue(&seq, 'a');
	PushQueue(&seq, 'b');
	PushQueue(&seq, 'c');
	PushQueue(&seq, 'd');
	PrintSeqQueue(&seq);
}

void TestPopQueue()
{
	TEAM_HEAD;
	SeqQueue seq;
	InitSeqQueue(&seq);
	PushQueue(&seq, 'a');
	PushQueue(&seq, 'b');
	PushQueue(&seq, 'c');
	PushQueue(&seq, 'd');
	PushQueue(&seq, 'e');
	PrintSeqQueue(&seq);
	PopQueue(&seq);
	PopQueue(&seq);
	PopQueue(&seq);
	PopQueue(&seq);
	PrintSeqQueue(&seq);
	PushQueue(&seq, 'f');
	PushQueue(&seq, 'g');
	PushQueue(&seq, 'h');
	PushQueue(&seq, 'i');
	PushQueue(&seq, 'j');
	PushQueue(&seq, 'k');
	PrintSeqQueue(&seq);
}

void TestFindButtom()
{
	TEAM_HEAD;
	SeqQueue seq;
	InitSeqQueue(&seq);
	PushQueue(&seq, 'a');
	PushQueue(&seq, 'b');
	PushQueue(&seq, 'c');
	PushQueue(&seq, 'd');
	PushQueue(&seq, 'e');
	PrintSeqQueue(&seq);
	QueueType ret = FindButtom(&seq);
	printf("except e actual %c",ret);
}

void TestFindHead()
{
	TEAM_HEAD;
	SeqQueue seq;
	InitSeqQueue(&seq);
	PushQueue(&seq, 'a');
	PushQueue(&seq, 'b');
	PushQueue(&seq, 'c');
	PushQueue(&seq, 'd');
	PushQueue(&seq, 'e');
	PrintSeqQueue(&seq);
	PopQueue(&seq);
	PopQueue(&seq);
	PopQueue(&seq);
	PopQueue(&seq);
	PrintSeqQueue(&seq);
	PushQueue(&seq, 'f');
	PushQueue(&seq, 'g');
	PushQueue(&seq, 'h');
	PushQueue(&seq, 'i');
	PushQueue(&seq, 'j');
	PushQueue(&seq, 'k');
	PrintSeqQueue(&seq);
	QueueType ret = FindHead(&seq);
	printf("except e actual %c",ret);
}

void TestDestoryQueue()
{
	TEAM_HEAD;
	SeqQueue seq;
	InitSeqQueue(&seq);
	PushQueue(&seq, 'a');
	PushQueue(&seq, 'b');
	PushQueue(&seq, 'c');
	PushQueue(&seq, 'd');
	PushQueue(&seq, 'e');
	PrintSeqQueue(&seq);
	DestoryQueue(&seq);
	PrintSeqQueue(&seq);
}

int main()
{
	TestInitSeqQueue();
	TestPushQueue();
	TestPopQueue();
	TestFindButtom();
	TestFindHead();
	TestDestoryQueue();
	return 0;
}

順序表迴圈佇列中,最需要注意的就是在順序表到達最大位置時,

需要將size置為0,所以我們添加了一個變數count來計數隊中元素的個數,

這樣就可以判斷佇列是否滿,還有在列印佇列中也需要注意列印的順序,是從前往後列印還是相反

要明確。我呢,是採用從隊尾列印,也就是先列印呢size值大的。

如有不足請多多指教。