1.定义

  

  栈:后进先出(LIFO-last in first out):最后插入的元素最先出来。

  队列:先进先出(FIFO-first in first out):最先插入的元素最先出来。

2.用数组实现栈和队列

实现栈:

  由于数组大小未知,如果每次插入元素都扩展一次数据(每次扩展都意味着构建一个新数组,然后把旧数组复制给新数组),那么性能消耗相当严重。

  这里使用贪心算法,数组每次被填满后,加入下一个元素时,把数组拓展成现有数组的两倍大小。

  每次移除元素时,检测数组空余空间有多少。当数组里的元素个数只有整个数组大小的四分之一时,数组减半。

  为什么不是当数组里的元素个数只有整个数组大小的二分之一时,数组减半?考虑以下情况:数组有4个元素,数组大小为4个元素空间。此时,加一个元素,数组拓展成8个空间;再减一个元素,数组缩小为4个空间;如此循环,性能消耗严重。

  具体代码(Java):

  

public ResizingArrayStackOfStrings()
{
s=new String[1];
int N = 0;
} pubilc void Push(String item)
{
//如果下一个加入元素超出数组容量,拓展数组
if(N == s.length) Resize(2 * s.length);
s[N++] = item;
} private void Resize(int capacity)
{
String[] copy = new String[capacity];
//将旧数组元素复制给新数组
for(int i=0; i<N; i++) copy[i] = s[i];
s = copy;
} public String Pop()
{
String item = s[--N];
s[N] = null;
//剩余元素只占数组四分之一空间时,数组减半
if(N>0 && N=s.length/4) Resize(s.length/2);
return item;
}

效果如下图:

实现队列

  与栈类似:

数组每次被填满后,加入下一个元素时,把数组拓展成现有数组的两倍大小。

  每次移除元素时,检测数组空余空间有多少。当数组里的元素个数只有整个数组大小的四分之一时,数组减半。

  不同之处在于:

由于是先进先出,移除是从队列的最前端开始的。所以当我们移除数个数据后,队列数据是存储在数组的中间部分的。令队列数据的尾端数据ID为Num,首端数据ID为HeadIndex,则Num - HeadIndex为队列数据元素个数。

当队列数据元素个数为整个数组空间的四分之一时,数组减半,且队列数据左移至数组最左端。即Num-=HeadIndex;HeadIndex=0;

  图中,HeadIndex=2;Num=5;

具体代码:

.h:

UCLASS()
class ALGORITHM_API AStackAndQueuesExerciseTwo : public AActor
{
GENERATED_BODY() public:
// Sets default values for this actor's properties
AStackAndQueuesExerciseTwo();
// Called every frame
virtual void Tick(float DeltaTime) override;
//输入
void Enqueue(int Input);
//重构数组(拓展或缩小)
void Resize(int Capacity);
//输出且移除
int Dequeue();
//队列里没元素了?
bool IsEmpty(); protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override; public: private:
//记录数组中有多少个Int
int Num;
//队列数组
TArray<int> MyIntArray;
//记录下一个移除的数据ID
int HeadIndex;
}; .cpp: AStackAndQueuesExerciseTwo::AStackAndQueuesExerciseTwo()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//一开始数组没成员
Num = ;
HeadIndex = ;
//数组中有一个假元素
MyIntArray.Add();
} // Called when the game starts or when spawned
void AStackAndQueuesExerciseTwo::BeginPlay()
{
Super::BeginPlay();
//测试
Enqueue();
Enqueue();
Enqueue();
Enqueue();
Enqueue();
Dequeue();
Dequeue();
Dequeue();
//队列数组成员
for (int i = HeadIndex; i < Num; i++)
{
UKismetSystemLibrary::PrintString(this, "i: " + FString::FromInt(i) + " End: " + FString::FromInt(MyIntArray[i]));
}
//队列数组的容量
UKismetSystemLibrary::PrintString(this, "MyIntArray.Num(): " + FString::FromInt(MyIntArray.Num()));
} // Called every frame
void AStackAndQueuesExerciseTwo::Tick(float DeltaTime)
{
Super::Tick(DeltaTime); } void AStackAndQueuesExerciseTwo::Enqueue(int Input)
{
//如果队列数组已满,拓展数组
if (Num == MyIntArray.Num())
{
Resize( * MyIntArray.Num());
}
//拓展或者数组有空位时,添加元素
if (Num < MyIntArray.Num())
{
MyIntArray[Num] = Input;
}
Num++;
} void AStackAndQueuesExerciseTwo::Resize(const int Capacity)
{
//int a[] = new int[Capacity];
TArray<int> Copy;
//添加数个假元素填充数组
for (int i = ; i < Capacity; i++)
{
Copy.Add();
}
//将队列数组赋值给Copy数组,如果是缩小数组,则把队列数组左移,节省空间
for (int i = HeadIndex; i < Num; i++)
{
Copy[i - HeadIndex] = MyIntArray[i];
}
MyIntArray = Copy;
} int AStackAndQueuesExerciseTwo::Dequeue()
{
//判断数组是否为空
if (IsEmpty())
{
UKismetSystemLibrary::PrintString(this, "No Element Exist!!!");
return ;
}
else
{
UKismetSystemLibrary::PrintString(this, "Dequeue: " + FString::FromInt(MyIntArray[HeadIndex]));
}
HeadIndex++;
//如果移除元素后,所剩元素为数组空间的四分之一,则数组减半
if ((Num - HeadIndex) != && (Num - HeadIndex) == (MyIntArray.Num() / ))
{
Resize(MyIntArray.Num() / );
//移除空间后,队列数组左移,节省空间
Num -= HeadIndex;
HeadIndex = ;
return MyIntArray[HeadIndex];
}
else
{
return MyIntArray[HeadIndex - ];
} }
//如果下一个要移除的数据不存在,则为空数组
bool AStackAndQueuesExerciseTwo::IsEmpty()
{
return HeadIndex >= Num;
}

栈与队列(Stack and Queue)的更多相关文章

  1. Coursera Algorithms week2 栈和队列 练习测验: Queue with two stacks

    题目原文: Implement a queue with two stacks so that each queue operations takes a constant amortized num ...

  2. LeetCode 232题用栈实现队列(Implement Queue using Stacks) Java语言求解

    题目链接 https://leetcode-cn.com/problems/implement-queue-using-stacks/ 题目描述 使用栈实现队列的下列操作: push(x) -- 将一 ...

  3. C#LeetCode刷题之#232-用栈实现队列​​​​​​​​​​​​​​(Implement Queue using Stacks)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4108 访问. 使用栈实现队列的下列操作: push(x) -- ...

  4. LeetCode 232. 用栈实现队列(Implement Queue using Stacks) 4

    232. 用栈实现队列 232. Implement Queue using Stacks 题目描述 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从 ...

  5. Leedcode算法专题训练(栈和队列)

    1. 用栈实现队列 232. Implement Queue using Stacks (Easy) Leetcode / 力扣 class MyQueue { Stack<Integer> ...

  6. lintcode :implement queue by two stacks 用栈实现队列

    题目 用栈实现队列 正如标题所述,你需要使用两个栈来实现队列的一些操作. 队列应支持push(element),pop() 和 top(),其中pop是弹出队列中的第一个(最前面的)元素. pop和t ...

  7. [Swift]LeetCode232. 用栈实现队列 | Implement Queue using Stacks

    Implement the following operations of a queue using stacks. push(x) -- Push element x to the back of ...

  8. LeetCode 232:用栈实现队列 Implement Queue using Stacks

    题目: 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- 返回队列首部的元素. empty() -- 返回队列是 ...

  9. LeetCode#232-Implement Queue using Stacks-用栈实现队列

    一.题目 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- 返回队列首部的元素. empty() -- 返回队列 ...

随机推荐

  1. 转 Deep Learning for NLP 文章列举

    原文链接:http://www.xperseverance.net/blogs/2013/07/2124/   大部分文章来自: http://www.socher.org/ http://deepl ...

  2. 逆袭之旅DAY28.XIA.异常处理

    2018-07-24  14:42:24 第一种: 第二种: 第三种:  执行 try--catch--finally--return(执行return  退出方法) 代码示例: 输入数字,输出对应课 ...

  3. 1-3Controller之Response

    控制器中的方法: public function response1(){ /*响应的常见类型: * 1.字符串 * 2.视图 * 3.json * 4.重定向 * */ //响应JSON /*$da ...

  4. jquery 元素选择器

    id选择器 JQuery 能使用CSS选择器来操作网页中的标签元素.如果想要通过一个id号去查找另一个元素就可以使用下面格式的选择 $('#my_id') 其中my_id表示根据id选择器获取页面中的 ...

  5. 输出链表的倒数第K个值

    题目描述 输入一个链表,输出该链表中倒数第k个结点.   思路一:链表不能向前遍历,只能向后遍历.因此倒数第K个结点就是 正序的  :len(链表)-1-K的下一个.  注意,此处的思路与代码中具体实 ...

  6. 初学Linux系统最应该做对的4件事情[长文]

    “闲来无事,逛逛贴吧”已经是本人无事消磨时间的最佳选择了.五花八门的问题,各式各样的回答,总能给自己带来无限的欢乐.当然也有些问题值得自己去思考或者回答.之前就有人在贴吧里问到“Linux好难啊!该怎 ...

  7. asp.net MVC之Action过滤器浅析

    在asp.net MVC中,Action过滤器是一大利器,它可以在以下两个步骤执行相关的代码: 1.执行Action方法之前:OnActionExecuting 2.Action方法执行完毕后:OnA ...

  8. 归并排序(Merging Sort)

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  9. C数据结构 : 线性表 与 链表

    一.线性表 一般表现为数组,使用一组地址连续的存储单元依次存储数据元素,如图: 它具有如下特点: 长度固定,必须在分配内存之前确定数组的长度. 存储空间连续,即允许元素的随机访问. 存储密度大,内存中 ...

  10. DevExpress v18.1新版亮点——Reporting篇(二)

    用户界面套包DevExpress v18.1日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress Reporting v18.1 的新功能,快来下载试用新版本 ...