上一篇文章我說了順序隊列的不足之處是常用的Append操作時間複雜度是O(n),
所以我們下面就把它優化成O(1),閒話少說直接上代碼。
第九個例子,順序隊列優化版的實現:
頭文件
#ifndef _SEQQUEUE_H_
#define _SEQQUEUE_H_
typedef void SeqQueue;
SeqQueue* SeqQueue_Create(int capacity);
void SeqQueue_Destroy(SeqQueue* queue);
void SeqQueue_Clear(SeqQueue* queue);
int SeqQueue_Append(SeqQueue* queue, void* item);
int SeqQueue_Length(SeqQueue* queue);
int SeqQueue_Capacity(SeqQueue* queue);
void* SeqQueue_Retrieve(SeqQueue* queue);
void* SeqQueue_Header(SeqQueue* queue);
#endif
我個人有點小小的強迫症,代碼儘量要求簡潔,所以沒有註釋,有什麼不明白的可以留言。
實現文件
#include <stdio.h>
#include <malloc.h>
#include "SeqQueue.h"
typedef unsigned int TSeqQueueNode;
typedef struct tag_SeqQueue
{
int length;
int capacity;
int front;
int rear;
TSeqQueueNode* node;
} TSeqQueue;
SeqQueue* SeqQueue_Create(int capacity)
{
TSeqQueue* ret = NULL;
if (capacity >= 0)
{
ret = (TSeqQueue*)malloc(sizeof(TSeqQueue) + sizeof(TSeqQueueNode) * capacity);
}
if (ret)
{
ret->capacity = capacity;
ret->length = 0;
ret->front = 0;
ret->rear = 0;
ret->node = (TSeqQueueNode*)(ret + 1);
}
return ret;
}
void SeqQueue_Destroy(SeqQueue* queue)
{
free(queue);
}
void SeqQueue_Clear(SeqQueue* queue)
{
TSeqQueue* sQueue = (TSeqQueue*)queue;
if (sQueue != NULL)
{
sQueue->length = 0;
sQueue->front = 0;
sQueue->rear = 0;
}
}
int SeqQueue_Append(SeqQueue* queue, void* item)
{
TSeqQueue* sQueue = (TSeqQueue*)queue;
int ret = (sQueue != NULL) && (item != NULL);
ret = ret && ((sQueue->length + 1) <= sQueue->capacity);
if (ret)
{
sQueue->node[sQueue->rear] = (TSeqQueueNode)item;
sQueue->rear = (sQueue->rear + 1) % sQueue->capacity;
sQueue->length++;
}
return ret;
}
int SeqQueue_Length(SeqQueue* queue)
{
TSeqQueue* sQueue = (TSeqQueue*)queue;
int ret = -1;
if (sQueue != NULL)
{
ret = sQueue->length;
}
return ret;
}
int SeqQueue_Capacity(SeqQueue* queue)
{
TSeqQueue* sQueue = (TSeqQueue*)queue;
int ret = -1;
if (sQueue != NULL)
{
ret = sQueue->capacity;
}
return ret;
}
void* SeqQueue_Retrieve(SeqQueue* queue)
{
TSeqQueue* sQueue = (TSeqQueue*)queue;
void* ret = SeqQueue_Header(queue);
if (ret)
{
sQueue->front = (sQueue->front + 1) % sQueue->capacity;
sQueue->length--;
}
return ret;
}
void* SeqQueue_Header(SeqQueue* queue)
{
TSeqQueue* sQueue = (TSeqQueue*)queue;
void* ret = NULL;
if ((sQueue != NULL) && (sQueue->length > 0))
{
ret = (void*)sQueue->node[sQueue->front];
}
return ret;
}
跟順序表實現差不多吧!!!其實數據結構很多東西都是通用的。
#include <stdio.h>
#include <stdlib.h>
#include "SeqQueue.h"
int main(int argc, char *argv[])
{
SeqQueue* queue = SeqQueue_Create(20);
int a[10] = {0};
int i = 0;
for (i = 0; i < 10; i++)
{
a[i] = i + 1;
SeqQueue_Append(queue, a + i);
}
printf("capacity:%d\n", SeqQueue_Capacity(queue));
printf("length:%d\n", SeqQueue_Length(queue));
printf("header:%d\n", *((int*)SeqQueue_Header(queue)));
while (SeqQueue_Length(queue) > 0)
{
printf("retrieve:%d\n", *((int*)SeqQueue_Retrieve(queue)));
}
SeqQueue_Clear(queue);
SeqQueue_Destroy(queue);
system("PAUSE");
return 0;
}
測試文件跟上一個版本的一樣,原封不動,測試的結果跟上一個版本的結果一樣,
唯一的區別就是代碼的效率提高了。