上一篇中的队列的定义与实现(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. 达芬奇TI DVSDK之视频数据流过程分析

    作者:openwince@gmail.com 博客:http://www.cnblogs.com/tinz    本文的copyright归openwince@gmail.com所有,使用GPL发布, ...

  2. Nginx 作为反向Proxy 的优化要点

    原文地址:http://my.oschina.net/hyperichq/blog/405421 常用优化要点 当nginx用于反向代理时,每个客户端将使用两个连接: 一个用于响应客户端的请求,另一个 ...

  3. Android中的资源与国际化!

    Android中的资源与国际化的问题,通常我们新建一个Android工程,目录结构如下图所示: 我们主要看一下layout与values目录,layout里的xml文件的我们应用使用布局的文件,val ...

  4. XFire Web Service

    Web Service 创建HelloWorldService项目 首先要启动Web Service Project 向导.该向导由三个页面组成,第一页设置Web项目配置的详细信息:第二页设置XFir ...

  5. OpenCV学习(22) opencv中使用kmeans算法

    kmeans算法的原理参考:http://www.cnblogs.com/mikewolf2002/p/3368118.html 下面学习一下opencv中kmeans函数的使用.      首先我们 ...

  6. insert-delete-getrandom-o1

    // 参考了下面一些讨论的解法 // https://discuss.leetcode.com/topic/53235/java-with-hashtable-arraylist/2 class Ra ...

  7. TCP三次握手四次挥手相关问题探讨

    TCP的握手挥手和状态转换是很多网络问题的基础.在此进行相关问题的讨论及记录. 首先,这幅图大致介绍了TCP连接和断开的过程: 注意其中的几个状态: LISTEN, SYN-SEND, SYN-RCV ...

  8. 附1 rabbitmq常用命令

    1.rabbitmq的启动和停止 rabbitmq-server (前台启动) rabbitmq-server -detached(后台启动) rabbitmqctl stop(停止) 2.查看rab ...

  9. SonarQube代码质量管理平台 的安装、配置与使用

    SonarQube是管理代码质量一个开放平台,可以快速的定位代码中潜在的或者明显的错误,下面将会介绍一下这个工具的安装.配置以及使用. 准备工作: 1.jdk(不再介绍) 2.sonarqube:ht ...

  10. Bootstrap学习js插件篇之下拉菜单

    案例 通过此插件可以为几乎所有东西添加下拉菜单,包括导航条.标签页.胶囊式按钮. 用于导航条 导航条分为四个部分.第一部分导航头,第二部分导航列,第三部分form查询表单,第四部分导航列. <n ...