热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

数据结构封装之《SQueue栈式队列》

说明:本队列对是通过堆栈来实现的,一个inStack,一个outStack,通过两个栈的转移,以实现队列的功能;通过复用LinkStack的方法封装的SQueue,请看:数

说明:

  1. 本队列对是通过堆栈来实现的,一个inStack,一个outStack,通过两个栈的转移,以实现队列的功能;

  2. 通过复用LinkStack的方法封装的SQueue,请看:数据结构封装之《LinkStack链栈》

下面将给出该数据结构的代码,每个函数的结构分析 ,以及个别主要函数的汇编分析


代码:

LinkQueue.h

#ifndef _SQUEUE_H_
#define _SQUEUE_H_

typedef void SQueue;

SQueue* SQueue_Create();

void SQueue_Destroy(SQueue* queue);

void SQueue_Clear(SQueue* queue);

int SQueue_Append(SQueue* queue, void* item);

void* SQueue_Retrieve(SQueue* queue);

void* SQueue_Header(SQueue* queue);

int SQueue_Length(SQueue* queue);

#endif

LinkQueue.c

#include <stdio.h>
#include <malloc.h>
#include "LinkStack.h"
#include "SQueue.h"

typedef struct _tag_SQueue
{
LinkStack* inStack;
LinkStack* outStack;
} TSQueue;

SQueue* SQueue_Create() // O(1)
{
TSQueue* ret = (TSQueue*)malloc(sizeof(TSQueue));

if( ret != NULL )
{
ret->inStack = LinkStack_Create();
ret->outStack = LinkStack_Create();

if( (ret->inStack == NULL) || (ret->outStack == NULL) )
{
LinkStack_Destroy(ret->inStack);
LinkStack_Destroy(ret->outStack);

free(ret);

ret = NULL;
}
}

return ret;
}

void SQueue_Destroy(SQueue* queue) // O(n)
{
SQueue_Clear(queue);
free(queue);
}

void SQueue_Clear(SQueue* queue) // O(n)
{
TSQueue* sQueue = (TSQueue*)queue;

if( sQueue != NULL )
{
LinkStack_Clear(sQueue->inStack);
LinkStack_Clear(sQueue->outStack);
}
}

int SQueue_Append(SQueue* queue, void* item) // O(1)
{
TSQueue* sQueue = (TSQueue*)queue;
int ret = -1;
if( sQueue != NULL )
{
ret = LinkStack_Push(sQueue->inStack, item);
}
return ret;
}

void* SQueue_Retrieve(SQueue* queue) // O(1)
{
TSQueue* sQueue = (TSQueue*)queue;
void* ret = NULL;

if( sQueue != NULL )
{
if( LinkStack_Size(sQueue->outStack) == 0 )
{
while( LinkStack_Size(sQueue->inStack) > 0 )
{
LinkStack_Push(sQueue->outStack, LinkStack_Pop(sQueue->inStack));
}
}

ret = LinkStack_Pop(sQueue->outStack);
}

return ret;
}

void* SQueue_Header(SQueue* queue) // O(1)
{
TSQueue* sQueue = (TSQueue*)queue;
void* ret = NULL;

if( sQueue != NULL )
{
if( LinkStack_Size(sQueue->outStack) == 0 )
{
while( LinkStack_Size(sQueue->inStack) > 0 )
{
LinkStack_Push(sQueue->outStack, LinkStack_Pop(sQueue->inStack));
}
}

ret = LinkStack_Top(sQueue->outStack);
}

return ret;
}

int SQueue_Length(SQueue* queue) // O(1)
{
TSQueue* sQueue = (TSQueue*)queue;
int ret = -1;

if( sQueue != NULL )
{
ret = LinkStack_Size(sQueue->inStack) + LinkStack_Size(sQueue->outStack);
}

return ret;
}

main.c

#include 
#include
#include "SQueue.h"



int main(int argc, char *argv[])
{
SQueue* queue = SQueue_Create();
int a[10] = {0};
int i = 0;

for(i=0; i<10; i++)
{
a[i] = i + 1;

SQueue_Append(queue, a + i);
}

printf("Header: %d\n", *(int*)SQueue_Header(queue));
printf("Length: %d\n", SQueue_Length(queue));

for(i=0; i<5; i++)
{
printf("Retrieve: %d\n", *(int*)SQueue_Retrieve(queue));
}

printf("Header: %d\n", *(int*)SQueue_Header(queue));
printf("Length: %d\n", SQueue_Length(queue));

for(i=0; i<10; i++)
{
a[i] = i + 1;

SQueue_Append(queue, a + i);
}

while( SQueue_Length(queue) > 0 )
{
printf("Retrieve: %d\n", *(int*)SQueue_Retrieve(queue));
}

SQueue_Destroy(queue);

return 0;
}

函数结构分析:

1.LinkQueue_Create

2.LinkQueue_Destroy

3.LinkQueue_Clear

4.LinkQueue_Append

5.LinkQueue_Retrieve

6.LinkQueue_Header

7.LinkQueue_Length


汇编分析:

main

1.LinkQueue_Create

2.LinkQueue_Destroy

3.LinkQueue_Clear

4.LinkQueue_Append

5.LinkQueue_Retrieve

6.LinkQueue_Header

7.LinkQueue_Length


推荐阅读
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • BZOJ1233 干草堆单调队列优化DP
    本文介绍了一个关于干草堆摆放的问题,通过使用单调队列来优化DP算法,求解最多可以叠几层干草堆。具体的解题思路和转移方程在文章中进行了详细说明,并给出了相应的代码示例。 ... [详细]
  • 本文主要介绍了gym102222KVertex Covers(高维前缀和,meet in the middle)相关的知识,包括题意、思路和解题代码。题目给定一张n点m边的图,点带点权,定义点覆盖的权值为点权之积,要求所有点覆盖的权值之和膜qn小于等于36。文章详细介绍了解题思路,通过将图分成两个点数接近的点集L和R,并分别枚举子集S和T,判断S和T能否覆盖所有内部的边。文章还提到了使用位运算加速判断覆盖和推导T'的方法。最后给出了解题的代码。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 第七课主要内容:多进程多线程FIFO,LIFO,优先队列线程局部变量进程与线程的选择线程池异步IO概念及twisted案例股票数据抓取 ... [详细]
author-avatar
woshishl
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有