上一篇中的队列的定义与实现(C语言实现) 中。不管是顺序队列还是链式队列,在尾加和删除头部的操作时。总有一个时间复杂度让人不惬意。

比方在顺序队列中,删除头部的操作后,总要将后面全部的结点都向前移动一位,这里消耗的较大的。又如在在链式队列中。尾加结点时,为了寻找到最后一位结点,要遍历整个队列,时间复杂度相同是O(n)。

为此,这里须要做出一些改变。当中严蔚敏老师的数据结构书中就是这么干的。

循序队列的优化方案:

定义front使其始终代表队头的下标

 出队时将队头元素返回,且 且front++

定义rear使其始终代表队尾下一个元素的下标

 入队时将新元素插入, 且rear++

头文件:

#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); void* SeqQueue_Retrieve(SeqQueue* queue); void* SeqQueue_Header(SeqQueue* queue); int SeqQueue_Length(SeqQueue* queue); int SeqQueue_Capacity(SeqQueue* queue); #endif

源文件:

// 优化的顺序队列.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include "SeqQueue.h"
#include <stdlib.h> typedef unsigned int TSeqQueueNode; typedef struct _tag_SeqQueue
{
int capacity;
int length;
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 (NULL != ret)
{
ret->capacity = capacity;
ret->front = 0; //代表队头的下标
ret->length = 0; //长度
ret->node = (TSeqQueueNode*)(ret + 1); //指向的结点
ret->rear = 0; //队尾下一个结点的下标
}
return ret;
} void SeqQueue_Destroy(SeqQueue* queue)
{
free(queue);
} void SeqQueue_Clear(SeqQueue* queue)
{
TSeqQueue* sQueue = (TSeqQueue*)queue;
if (NULL != sQueue)
{
sQueue->front = 0; //代表队头的下标
sQueue->length = 0; //长度
sQueue->rear = 0; //队尾下一个结点的下标
}
}
//在尾部插入
int SeqQueue_Append(SeqQueue* queue, void* item)
{
TSeqQueue* sQueue = (TSeqQueue*)queue;
int ret = 0;
if ((NULL != sQueue) && (NULL != item) && (sQueue->length+1 <= sQueue->capacity))
{
ret = 1;
sQueue->node[sQueue->rear] = (TSeqQueueNode)item;
sQueue->rear = (sQueue->rear + 1) % sQueue->capacity;
sQueue->length++ ;
}
return ret;
} //删除头部
void* SeqQueue_Retrieve(SeqQueue* queue)
{
TSeqQueue* sQueue = (TSeqQueue*)queue;
void* ret = SeqQueue_Header(queue); if( ret != NULL )
{
sQueue->front = (sQueue->front + 1) % sQueue->capacity; sQueue->length--;
} return ret;
} //获得头部
void* SeqQueue_Header(SeqQueue* queue)
{
TSeqQueue* sQueue = (TSeqQueue*)queue;
void* ret = NULL;
if ((NULL != sQueue) && (sQueue->length > 0))
{
ret = (void*)(sQueue->node[sQueue->front]);
}
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;
} int _tmain(int argc, _TCHAR* 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("Header: %d\n", *(int*)SeqQueue_Header(queue));
printf("Length: %d\n", SeqQueue_Length(queue));
printf("Capacity: %d\n", SeqQueue_Capacity(queue)); while( SeqQueue_Length(queue) > 0 )
{
printf("Retrieve: %d\n", *(int*)SeqQueue_Retrieve(queue));
} SeqQueue_Destroy(queue); system("pause");
return 0;
}

执行结果:

Header: 1
Length: 10
Capacity: 20
Retrieve: 1
Retrieve: 2
Retrieve: 3
Retrieve: 4
Retrieve: 5
Retrieve: 6
Retrieve: 7
Retrieve: 8
Retrieve: 9
Retrieve: 10
请按随意键继续. . .

=========================================================================

链式队列的优化:

定义front指针始终指向链表中的第一个结点

定义rear指针始终指向链表中的最后一个结点

&#1; 入队时将新元素通过rear插入队尾, 且将rear指向新元素

头文件:

#ifndef _LINKQUEUE_H_
#define _LINKQUEUE_H_ typedef void LinkQueue; LinkQueue* LinkQueue_Create(); void LinkQueue_Destroy(LinkQueue* queue); void LinkQueue_Clear(LinkQueue* queue); int LinkQueue_Append(LinkQueue* queue, void* item); void* LinkQueue_Retrieve(LinkQueue* queue); void* LinkQueue_Header(LinkQueue* queue); int LinkQueue_Length(LinkQueue* queue); #endif

源文件:

// 优化的链式队列.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <malloc.h>
#include <stdlib.h>
#include "LinkQueue.h" typedef struct _tag_LinkQueueNode TLinkQueueNode;
struct _tag_LinkQueueNode
{
TLinkQueueNode* next;
void* item;
}; typedef struct _tag_LinkQueue
{
TLinkQueueNode* front;
TLinkQueueNode* rear;
int length;
} TLinkQueue; int _tmain(int argc, _TCHAR* argv[])
{ LinkQueue* queue = LinkQueue_Create();
int a[10] = {0};
int i = 0; for(i=0; i<10; i++)
{
a[i] = i + 1; LinkQueue_Append(queue, a + i);
} printf("Header: %d\n", *(int*)LinkQueue_Header(queue));
printf("Length: %d\n", LinkQueue_Length(queue)); while( LinkQueue_Length(queue) > 0 )
{
printf("Retrieve: %d\n", *(int*)LinkQueue_Retrieve(queue));
} LinkQueue_Destroy(queue); system("pause");
return 0;
} LinkQueue* LinkQueue_Create()
{
TLinkQueue* ret = (TLinkQueue*)malloc(sizeof(TLinkQueue));
if (NULL != ret)
{
ret->front = NULL;
ret->length = 0;
ret->rear = NULL;
}
return ret;
}
void LinkQueue_Destroy(LinkQueue* queue) // O(n)
{
LinkQueue_Clear(queue);
free(queue);
} void LinkQueue_Clear(LinkQueue* queue) // O(n)
{
while( LinkQueue_Length(queue) > 0 )
{
LinkQueue_Retrieve(queue);
}
} int LinkQueue_Append(LinkQueue* queue, void* item)
{
TLinkQueue * sQueue= (TLinkQueue*)queue;
TLinkQueueNode * node = (TLinkQueueNode*)malloc(sizeof(TLinkQueueNode));
int ret = 0;
if ((NULL != queue) && (NULL != item) && (NULL != node))
{
ret = 1;
node->item = item;
if (sQueue->length > 0)
{
sQueue->rear->next = node;
sQueue->rear = node;
node->next = NULL;
}
else
{
sQueue->front = node;
sQueue->rear = node;
node->next = NULL;
}
sQueue->length++;
}
if( !ret )
{
free(node);
} return ret;
} void* LinkQueue_Retrieve(LinkQueue* queue)
{
TLinkQueue* sQueue = (TLinkQueue*)queue;
TLinkQueueNode* node = NULL;
void* ret = NULL; if( (sQueue != NULL) && (sQueue->length > 0) )
{
node = sQueue->front; sQueue->front = node->next; ret = node->item; free(node); sQueue->length--; if( sQueue->length == 0 )
{
sQueue->front = NULL;
sQueue->rear = NULL;
}
} return ret; }
void* LinkQueue_Header(LinkQueue* queue) // O(1)
{
TLinkQueue* sQueue = (TLinkQueue*)queue;
void* ret = NULL; if( (sQueue != NULL) && (sQueue->length > 0) )
{
ret = sQueue->front->item;
} return ret;
} int LinkQueue_Length(LinkQueue* queue) // O(1)
{
TLinkQueue* sQueue = (TLinkQueue*)queue;
int ret = -1; if( sQueue != NULL )
{
ret = sQueue->length;
} return ret;
}

执行结果:

Header: 1
Length: 10
Retrieve: 1
Retrieve: 2
Retrieve: 3
Retrieve: 4
Retrieve: 5
Retrieve: 6
Retrieve: 7
Retrieve: 8
Retrieve: 9
Retrieve: 10
请按随意键继续. . .

如有错误,望不吝指出。

优化后队列的实现(C语言实现)的更多相关文章

  1. topo排序 + 用邻接表优化后的

    输入数据: 4 61 21 32 33 42 44 2 4 61 21 32 33 42 41 2 topo排序为偏序: #include<stdio.h> #include<que ...

  2. Tomcat 7优化前及优化后的性能对比

    Tomcat 7在我们日常开发.测试.生产环境都会使用到,但对于大部分开发人员来说,对其性能还是没有多大了解.本文就对它做一次性能测试,对比优化前后的性能区别. 一.运行环境 CPU: Intel(R ...

  3. [大牛翻译系列]Hadoop(21)附录D.1 优化后的重分区框架

    附录D.1 优化后的重分区框架 Hadoop社区连接包需要将每个键的所有值都读取到内存中.如何才能在reduce端的连接减少内存开销呢?本文提供的优化中,只需要缓存较小的数据集,然后在连接中遍历较大数 ...

  4. 无语的index hint:手工分配哈希区,5小时不出结果,优化后20分钟

    同事说,有个语句5个小时不出结果,叫我帮忙看看,于是叫同事发过来.不看不知道,一看吓一跳,3个表关联,强制使用了2个index hint,当中一个表9g,一个表67g,另一个小表40Mb.开发者,总以 ...

  5. [Linux] Nginx 提供静态内容和优化积压队列

    1.try_files指令可用于检查指定的文件或目录是否存在; NGINX会进行内部重定向,如果没有,则返回指定的状态代码.例如,要检查对应于请求URI的文件是否存在,请使用try_files指令和$ ...

  6. 【题解】Cats Transport (斜率优化+单调队列)

    [题解]Cats Transport (斜率优化+单调队列) # When Who Problem Lang Verdict Time Memory 55331572 Jun/09/2019 19:1 ...

  7. 《编译原理》画 DAG 图与求优化后的 4 元式代码- 例题解析

    <编译原理>画 DAG 图与求优化后的 4 元式代码- 例题解析 DAG 图(Directed Acylic Graph)无环路有向图 (一)基本块 基本块是指程序中一顺序执行的语句序列, ...

  8. Mysql查看优化后的SQL 语句

    EXPLAIN  EXTENDED 1先执行 EXPLAIN  EXTENDED 2 show warnings: EXPLAIN EXTENDED SELECT * FROM `receivable ...

  9. 使用matlab用优化后的梯度下降法求解达最小值时参数

    matlab可以用 -Conjugate gradient -BFGS -L-BFGS 等优化后的梯度方法来求解优化问题.当feature过多时,最小二乘计算复杂度过高(O(n**3)),此时 这一些 ...

随机推荐

  1. USB Mass Storage大容量存储 The Thirteen Class章节的理解

    http://blog.csdn.net/xgbing/article/details/7002558 USB Mass Storage 6.7 The Thirteen Class章节的理解 Cas ...

  2. Kernel Newbies内核开发新手的资源

    Jessica McKellar在Ksplice blog上的博客文章 <Linux Device Drivers> 如果你在写一个操作系统,OSDev wiki是一个不错的网站 Kern ...

  3. 用VC资源动态链接库解决国际化问题

    http://daixinghe.blog.163.com/blog/static/1843615920097181952979/ 随着计算机应用的普及,应用软件跨国使用越来越频繁,如何实现应用软件的 ...

  4. 开启PowerDesigner15工具栏上的被禁用掉的图标

    PowerDesigner 15 的版本,工具栏上的Inheritance图标默认是禁用的,如下图所示:

  5. MySQL 5.5版本解决中文乱码问题时my.ini内[mysqld]项中不能再写default-character-set=utf8

    来看看如何解决乱码问题: 在mysql中默认字符集是latin1, 想要设置字符集为uft-8,可以在 my.cnf 文件中添加以下设置: [client] default-character-set ...

  6. msgpack和protobuf的对比

    msgpack和protobuf的对比 msgpack的序列化速度比protobuf要快一些,但反序列化要比protobuf要慢一些,但总体都接近msgpack可以直接序列化类对象,但protobuf ...

  7. restful处理

    重写/覆盖   HTTP 方法 一些HTTP客户端仅能处理简单的的GET和POST请求,为照顾这些功能有限的客户端,API需要一种方式来重写HTTP方法. 尽管没有一些硬性标准来做这事,但流行的惯例是 ...

  8. mybatis映射文件遇到的小问题

    mybatis的映射文件插入操作时: 如果对应的属性是String类型的,那么一定要做空串的判断. 比如注册的时候,如果需要向数据库中插入一条记录时,对应的字段没有给他赋值,这个String类型的值传 ...

  9. eclipse svn 配置

    1.安装svn http://subversion.apache.org/ 到apache网站上下载svn 2.在eclipse中安装svn插件 在eclipse->help->eclip ...

  10. 使用标准模板find函数来对结构体容器进行查找

    最近在写一个项目,项目中需要获得类下面的所有对象,所以我采用了map容器,以string为关键字,list容器为内容来进行查找,而list中是一些struct结构体.由于在插入操作的时候需要判断该对象 ...