上一篇中的队列的定义与实现(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. 给Android组件添加事件一个很好用的方法

    在这里想和大家分享一下很好用的添加事件方法,特别是在处理ListView里的Item事件的时候,很方便. 首先,在XML里布局的时候,添加这样一个属性: android:onClick="C ...

  2. winform datagridview 打印

    转载:http://www.cnblogs.com/Irving/archive/2012/10/12/2721666.html c#实现打印功能 http://www.cnblogs.com/zhc ...

  3. Windows Phone Silverlight 8.1 apps

    The Windows Phone Silverlight 8.1 app model gives Windows Phone 8 developers access to some of the n ...

  4. ubuntu 键盘布局修改

    键盘打不出 | 符号 sudo dpkg-reconfigure keyboard-configuration 改为标准的罗技键盘

  5. [Git] 技术的热门度曲线

    reference :http://www.ruanyifeng.com/blog/2017/03/gartner-hype-cycle.html reference : https://stateo ...

  6. 使用SGD(Stochastic Gradient Descent)进行大规模机器学习

    原贴地址:http://fuliang.iteye.com/blog/1482002  其它参考资料:http://en.wikipedia.org/wiki/Stochastic_gradient_ ...

  7. request和request.form和request.querystring的区别

    asp中获取传递的参数,一般用request或者用request成员函数request.form,两种方式都可以获取页面表单传递过来的参数值,一直没留意两种方法有什么区别,我一般喜欢用request( ...

  8. Best Time to Buy and Sell Stock leetcode java

    题目: Say you have an array for which the ith element is the price of a given stock on day i. If you w ...

  9. operator++()和operator++(int)的区别

    很久以前(八十年代),没有办法区分++和--操作符的前缀与后缀调用.这个问题遭到程序员的报怨,于是C++语言得到了扩展,允许重载increment 和 decrement操作符的两种形式. 然而有一个 ...

  10. 关于帝国CMS迁移到新服务器上出现问题的处理办法

    在帝国CMS项目整体迁移过程中,或多或少总会出点幺蛾子,以下就常见的注意事项整理一下: 一.修改 e/config/config.php中的数据库相关配置 二.让项目文件位置具有读写权限 三.设置ph ...