算法导论 10.1-2 用一个数组实现两个栈

一、题目

用一个数组A[ 1....N ]实现两个栈,除非数组的每一个单元都被使用,否则栈例程不能有溢出,注意PUSH和POP操作的时间应为O(1)。

二、解法

对于一个数组,由它的两端作为栈底,栈向数组中间扩展。当数组中每个元素被用到时,栈满。

三、代码

struct Node;
typedef Node *ComStack;

struct Node
{
    int Capacity;
    int TopL;
    int TopR;
    ElementType *Array;
};

ComStack CreatComStack( int MaxElements );
int IsEmpty_L( ComStack S );
int IsEmpty_R( ComStack S );
int IsFull( ComStack S );
void MakeEmpty( ComStack S );
void Push_L( ElementType X, ComStack S );
void Push_R( ElementType X, ComStack S );
ElementType Pop_L( ComStack S );
ElementType Pop_R( ComStack S );
void DisposeComStack( ComStack S );

ComStack CreatComStack( int MaxElements )
{
    ComStack S;

    S = (ComStack)malloc( sizeof(struct Node) );
    if ( S == NULL )
    {
        printf( "Out of space" );
        return NULL;
    }

    S->Array = (ElementType *)malloc( sizeof(ElementType) * MaxElements );
    if ( S->Array == NULL )
    {
        printf( "Out of space" );
        return NULL;
    }

    S->Capacity = MaxElements;
    MakeEmpty(S);

    return S;
}

int IsEmpty_L( ComStack S )
{
    if ( S->TopL == -1 )
        return true;
    else
        return false;
}

int IsEmpty_R( ComStack S )
{
    if ( S->TopR == S->Capacity )
        return true;
    else
        return false;
}

int IsFull( ComStack S )
{
    if ( S->TopL + 1 == S->TopR )
        return true;
    else
        return false;
}

void MakeEmpty( ComStack S )
{
    S->TopL = -1;
    S->TopR = S->Capacity; // Capacity在数组界外
}

void Push_L(  ElementType X, ComStack S )
{
    if ( IsFull(S) )
        printf( "Stack is full" );
    else
    {
        S->TopL++;
        S->Array[S->TopL] = X;
    }
}

void Push_R( ElementType X, ComStack S )
{
    if ( IsFull(S) )
        printf( "Stack is full" );
    else
    {
        S->TopR--;
        S->Array[S->TopR] = X;
    }
}

ElementType Pop_L( ComStack S )
{
    ElementType TmpCell;

    if ( IsEmpty_L(S) )
        printf( "Left Stack is empty" );
    else
    {
        TmpCell = S->Array[S->TopL];
        S->TopL--;
    }

    return TmpCell;
}

ElementType Pop_R( ComStack S )
{
    ElementType TmpCell;

    if ( IsEmpty_R(S) )
        printf( "Right stack is empty" );
    else
    {
        TmpCell = S->Array[S->TopR];
        S->TopR++;
    }

    return TmpCell;
}

void DisposeComStack( ComStack S )
{
    if ( S != NULL )
    {
        free( S->Array );
        free( S );
    }
}
时间: 2024-10-08 10:30:20

算法导论 10.1-2 用一个数组实现两个栈的相关文章

一个数组实现两个栈

//1.两个栈栈头在数组头尾(利用率高) //2.两个栈栈头在数组中间(利用率低) //3.奇偶下标分别为两栈(扩容时复制数据简单) //实现1 template<class T> class Stack { public: Stack() :_array(NULL) , _q1Size(0) , _q2Size(0) , _capacity(0) {} ~Stack() { delete[] _array; _q1Size = _q2Size = _capacity = 0; } void 

包含MIN函数的栈+一个数组实现两个堆栈+两个数组实现MIN栈

1.题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数. 思路:利用一个辅助栈来存放最小值 栈  3,4,2,5,1 辅助栈 3,2,1 每入栈一次,就与辅助栈顶比较大小,如果小就入栈,如果大就不入栈当前的辅助栈:当出栈时,辅助栈元素相等时也要出栈. class Solution { public: stack<int> mystack1;//辅助栈 stack<int> minstack;//最小栈 void push(int value) { if(

一个数组构造两个堆栈

***用一个数组表示两个堆栈,最大限度的利用空间 0 1 2 3 若果像右图中从中间分成两部分,则可能存在其中一个堆栈满了,而另一个堆栈还有空的,为你最大限度的利用空间,需要两边像中间长,知道指针碰头表示堆栈已满 #include<iostream>using namespace std;#define Maxsize 100class stack{public: int a[Maxsize]; int top1; int top2;};void push(stack&A, int x

选择问题&mdash;&mdash;算法导论(10)

1. 引言     这一篇我们来探讨选择问题. 它的提法是: 输入:一个包含n个(互异)数的序列A和一个数i(1≤i≤n). 输出:元素x(x∈A),且A中有i-1个元素比x小. 简单的说,就是在A中找到第i小的数. 2. 期望为线性时间的选择算法 (1) 算法描述与实现     我们先给出算法的伪代码描述: 其主要思想与我们前面介绍的快速排序--算法导论(8)基本一样,只是在该问题中,我们每次递归时,只用考虑第i小的数可能出现的分组. 下面给出Java实现代码: public static v

算法导论:快速找出无序数组中第k小的数

题目描述: 给定一个无序整数数组,返回这个数组中第k小的数. 解析: 最平常的思路是将数组排序,最快的排序是快排,然后返回已排序数组的第k个数,算法时间复杂度为O(nlogn),空间复杂度为O(1).使用快排的思想,但是每次只对patition之后的数组的一半递归,这样可以将时间复杂度将为O(n). 在<算法导论>有详细叙述 这里主要用C++实现,实现思路就是先选取当前数组的第一个数作为"主轴",将后面所有数字分成两部分,前面一部分小于"主轴",后面一部

双端队列C实现代码 算法导论10.1-5 10.1-6 10.1-7

数组实现双端队列的时候注意区别判断上溢和下溢. 用两个栈实现队列,就相当于把两个栈底靠在一起(背靠背),一个栈用来出队列,一个栈用来进队列.这个队列的操作时间大部分时候是常数时间,除了出列的栈为空,需要把进列的栈全部转移过去,再出列.Back()操作和Pop()操作类似,也是这样. 而两个队列实现栈,队列轮流充当入栈和出栈的角色,而什么时候会改变角色呢,就是Pop()操作.Pop()操作先把一个队列中的所有元素全部出列并加入另外一个空队列中去,然后再出列(第二个队列). 实现代码为C #incl

算法导论10:栈链表的简化、队列的数组实现 2016.1.10

新年的前十天做了比较有意义的事情就是坚持每天写博客,明天就开始期末考试了,所以等假期再继续学习. 把昨天提到的S.bottom简化之后又改了栈的链表.代码如下(已折叠): #include<stdio.h> #include<stdlib.h> typedef struct _node{ int num; struct _node *next; }node; node *s; void build(node *&S) { s=(node *)malloc(sizeof(no

算法导论11:优化后的数组实现的队列 2016.1.11

本来想假期再继续,结果发现写博客已经成了总结自己的一种习惯,所以还是继续写吧. 其实有一部分原因是今天英语考砸了..哈哈,不管那些了,看来以后学习方式得改变一下,不能太功利,从简单开始,一点一点做好. 今天是队列的数组优化.昨天的队列有一个致命弱点,就是能盛放的数据数量越来越少,至于原因可以自己思考也可以上网搜索.如果是链表实现的话因为是动态分配空间,就完全不会有这个问题. 优化就是用了取模运算,实现数组空间的循环运用. 下面是代码: #include<stdio.h> #define MAX

算法导论 10.4 有根树的表示

10.4-2 给定n个结点的二叉树,写出一个O(n)时间的递归程序,将该树种每个结点的关键字输出. 伪代码: 1 TREE-PRINT(T) 2 if T != NIL 3 print key[T] 4 TREE-PRINT( left[T] ) 5 TREE-PRINT( right[T] ) c实现: void TreePrint( Tree T ) { if ( T != NULL ) { PrintElement( T ); TreePrint( T->left ); TreePrint