优化后队列的实现(C语言实现)
上一篇中的队列的定义与实现(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指针始终指向链表中的最后一个结点
 入队时将新元素通过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语言实现)的更多相关文章
- topo排序 + 用邻接表优化后的
输入数据: 4 61 21 32 33 42 44 2 4 61 21 32 33 42 41 2 topo排序为偏序: #include<stdio.h> #include<que ...
- Tomcat 7优化前及优化后的性能对比
Tomcat 7在我们日常开发.测试.生产环境都会使用到,但对于大部分开发人员来说,对其性能还是没有多大了解.本文就对它做一次性能测试,对比优化前后的性能区别. 一.运行环境 CPU: Intel(R ...
- [大牛翻译系列]Hadoop(21)附录D.1 优化后的重分区框架
附录D.1 优化后的重分区框架 Hadoop社区连接包需要将每个键的所有值都读取到内存中.如何才能在reduce端的连接减少内存开销呢?本文提供的优化中,只需要缓存较小的数据集,然后在连接中遍历较大数 ...
- 无语的index hint:手工分配哈希区,5小时不出结果,优化后20分钟
同事说,有个语句5个小时不出结果,叫我帮忙看看,于是叫同事发过来.不看不知道,一看吓一跳,3个表关联,强制使用了2个index hint,当中一个表9g,一个表67g,另一个小表40Mb.开发者,总以 ...
- [Linux] Nginx 提供静态内容和优化积压队列
1.try_files指令可用于检查指定的文件或目录是否存在; NGINX会进行内部重定向,如果没有,则返回指定的状态代码.例如,要检查对应于请求URI的文件是否存在,请使用try_files指令和$ ...
- 【题解】Cats Transport (斜率优化+单调队列)
[题解]Cats Transport (斜率优化+单调队列) # When Who Problem Lang Verdict Time Memory 55331572 Jun/09/2019 19:1 ...
- 《编译原理》画 DAG 图与求优化后的 4 元式代码- 例题解析
<编译原理>画 DAG 图与求优化后的 4 元式代码- 例题解析 DAG 图(Directed Acylic Graph)无环路有向图 (一)基本块 基本块是指程序中一顺序执行的语句序列, ...
- Mysql查看优化后的SQL 语句
EXPLAIN EXTENDED 1先执行 EXPLAIN EXTENDED 2 show warnings: EXPLAIN EXTENDED SELECT * FROM `receivable ...
- 使用matlab用优化后的梯度下降法求解达最小值时参数
matlab可以用 -Conjugate gradient -BFGS -L-BFGS 等优化后的梯度方法来求解优化问题.当feature过多时,最小二乘计算复杂度过高(O(n**3)),此时 这一些 ...
随机推荐
- socket缓冲区以及阻塞模式
socket缓冲区 每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区. write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从 ...
- 你得学会并且学得会的Socket编程基础知识(续)——Silverlight客户端
本文将在这个案例的基础上,加入一个特殊场景,利用Silverlight来实现客户端.有的朋友可能会说,其实是一样的吧.请不要急于下结论,有用过Silverlight的朋友都有这种体会,很多在标准.NE ...
- key-value 多线程server的Linux C++实现
项目需求 整体思路 网络通信 字符解析 数据存储与查询 1 存储管理 2 数据查询 多线程 待改进未实现的想法 GitHub源代码 项目需求 设计一个基于Socket或基于HTTP的server,服务 ...
- Lua简明教程
这几天系统地学习了一下Lua这个脚本语言,Lua脚本是一个很轻量级的脚本,也是号称性能最高的脚本,用在很多需要性能的地方,比如:游戏脚本,nginx,wireshark的脚本,当你把他的源码下下来编译 ...
- 【BZOJ】【4052】【CERC2013】Magical GCD
DP/GCD 然而蒟蒻并不会做…… Orz @lct1999神犇 首先我们肯定是要枚举下端点的……嗯就枚举右端点吧…… 那么对于不同的GCD,对应的左端点最多有log(a[i])个:因为每次gcd缩小 ...
- Hadoop目录
1. 通过java读取HDFS的数据 (转) 2. FLume监控文件夹,将数据发送给Kafka以及HDFS的配置文件详解 3. 开启hadoop和Hbase集群的lzo压缩功能(转) 4. Hado ...
- 在Spark上运行WordCount程序
1.编写程序代码如下: Wordcount.scala package Wordcount import org.apache.spark.SparkConf import org.apache.sp ...
- Android完全退出程序、线程
1.先添加权限 <uses-permission android:name="android.permission.RESTART_PACKAGES" /> 2.添加A ...
- iOS开发-Xcode入门ObjC程序
元旦三天假跟妹子冷战一天半,剩下的半天觉得无聊,可以写点东西,折腾了下xCode 6.1,虽然iPhone6比较丑,但是不影响IOS在高端机上面的地位,ObjC是扩充C的面向对象编程语言.主要使用于M ...
- Search a 2D Matrix leetcode java
题目: Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the f ...