优化后队列的实现(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)),此时 这一些 ...
随机推荐
- Apache Mina入门
Mina第一次听到这个名称的时候,我以为是个MM的名字米娜,后来才知道… Apache MINA(Multipurpose Infrastructure for Network Application ...
- java基础学习总结——static关键字
一.static关键字
- linux下如何挂接(mount)光盘镜像文件、移动硬盘、U盘、Windows网络共享和NFS网络共享
首先,介绍一下挂接(mount)命令的使用方法,mount命令参数非常多,这里主要讲一下今天我们要用到的. 命令格式: mount [-t vfstype] [-o options ...
- joel 相关
1. stack overflow , http://blog.jobbole.com/102810/, stack overflow 提问也是一门学问. 2. tello 类似于 leangoo,一 ...
- [翻译] ClockView 时钟
ClockView 时钟 https://github.com/nacho4d/ClockView Overview ClockView is s simple class that will sim ...
- Java Net版短网址(ShortUrl)的算法及实现 待续
算法 1)将长网址md5生成32位签名串,分为4段, 每段8个字节; 2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略处理; 3) ...
- strstr实现
// strstr.c查找完全匹配的子字符串 #include<stdio.h> #include<string.h> char *my_strstr(const char * ...
- connection to sys should be as sysdba or sysoper 解决的方法
连接时提示: 出现了例如以下的情况:EXP-00056;遇到ORACLE错误28009. ORA-28009:connection to sys should be as sy ...
- guess-number-higher-or-lower-ii
// https://discuss.leetcode.com/topic/51353/simple-dp-solution-with-explanation // https://en.wikipe ...
- tensorflow 之常见模块conv,bn...实现
使用tensorflow时,会发现tf.nn,tf.layers, tf.contrib模块有很多功能是重复的,尤其是卷积操作,在使用的时候,我们可以根据需要现在不同的模块.但有些时候可以一起混用. ...