数据结构之栈

1. 栈介绍:

    栈是限定仅在表尾进行插入或者删除操作的线性表。因此,对于栈而言,表尾端有其特殊意义,成为栈顶(top),表头端称为栈底。栈又称为后进先出的顺序表。

2.栈的功能介绍:

    栈的功能函数有:插入,删除,获取栈顶元素,获取长度,判断栈是否为空。

    (1) 栈的基本定义代码如下:

template<typename Type>
class Stack
{
private:
    Type *data;    
    int length;                
    int MAX;                  
public:
    Stack();
    ~Stack();
    Type top();            
    bool pop();             
    bool empty();               
    void push(Type data);       
    void clear();            
    int size();              
};

    (2) 插入

    函数原型:void push(Type data)

    介绍:插入时,首先需要判断一下栈是否已经满了,满了的话重新分配空间。分配空间的原则和模板类vector一样,以原来的两倍为新的空间,然后将数据重新复制过去,复杂度为栈的长度。没有满的时候直接插入。

template<typename Type>
void Stack<Type>::push(Type number)
{
    if(this->length == this->MAX)
    {
        Type* data = new Type[this->length*2];
        for(int i=0;i<this->length;i++)
        {
            data[i] = this->data[i];
        }
        data[this->length] = number;
        if(this->data != NULL)delete[] this->data;
        this->data = data;
        this->length = this->length+1;
        this->MAX = this->MAX*2;
    }
    else
    {
        this->data[this->length++] = number;
    }
}

    (3) 删除

    函数原型:bool pop()

    介绍:删除比较简单,只需要将length-1就好了。如果栈中没有元素,返回false,否则,删除后返回true。

template<typename Type>
bool Stack<Type>::pop()
{
    if(this->length == 0) return false;
    else
    {
        length--;
        return true;
    }
}

    (4) 其他比较简单,读者可以自行完成。

3.栈的应用

    (1) 进制的变换

    (我的例子是以十进制为输入,以mod进制返回,读者可以自己写个m进制转n进制的。思路也差不多,先把m进制转成10进制,然后再进行一下变化。此外,我的代码不支持32位以上的,如果有需要,可以自行写个高精度进制转换。)

    进制的转换无非就是存余数,算出商,存余数,算出商......举个简单的例子,11(10)转成x(2),问x等于几。

NN/2N%2
1151
521
210
101

    那么11(10)=1011(2)

int Change(int Num,int mod)
{
    Stack<int> stack = Stack<int>();
    while(Num)
    {
        stack.push(Num%mod);
        Num = Num/mod;
    }
    int afterNum = 0;
    while(!stack.empty())
    {
        afterNum = afterNum * 10 + stack.top();
        stack.pop();
    }
    return afterNum;
}

    (2) 括号匹配

    括号匹配也很简单,先判断是否为'('/'[',是,则直接插入栈,否则,如果不是这两种组合('('和')')/('['和']')则返回false。直到列表扫描完毕,如果此时栈不为空,则返回false,否则,返回true。

bool isOk(char *str)
{
    Stack<char> stack = Stack<char>();
    int len = strlen(str);
    for(int i=0;i<len;i++)
    {
        if(str[i] == '(' || str[i] == '[')
            stack.push(str[i]);
        else
        {
            if(stack.size() == 0) return false;
            if(str[i] == ')' && stack.top() != '(') return false;
            if(str[i] == ']' && stack.top() != '[') return false;
            stack.pop();
        }
    }
    if(stack.size() == 0) return true;
    else return false;
}

    (3) 行编辑程序。

    觉得这个没什么好讲的。觉得那个输出比较适合用队列做,不过删除一个元素和一行元素比较适合用栈做,都可以吧。

void LinkEdit(char *ch)
{
    Stack<char> stack = Stack<char>();
    int len = strlen(ch);
    for(int i=0;i<len;i++)
    {
        while(i < len && ch[i] != '\n')
        {
            switch(ch[i])
            {
                case '#':
                    if(!stack.empty()) stack.pop();
                    break;
                case '@':
                    stack.clear();
                    break;
                default:
                    stack.push(ch[i]);
            }
            i++;
        }
        char *str = new char[stack.size() + 1];
        int num = 0;
        while(!stack.empty())
        {
            str[num++] = stack.top();
            stack.pop();
        }
        str[num] = '\0';
        for(int j=0;j<num/2;j++)
            swap(str[j],str[num-j-1]);
        printf("%s\n",str);
        delete[] str;
        stack.clear();
    }
}

    (4) 迷宫求解问题

    (5) 表达式求值

    *以上两个我还在做总结,等做完之后在一起整理出来。迷宫求解问题也可以用队列做。迷宫求解问题也可以推广到扫雷雷生成问题,思路是一样的。此外,除了这些例子,面试中最常见的还是给你入栈顺序,问你一下那个出栈顺序是不满足的。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值