数据结构(三)——栈

一:栈的概述

栈是一个先进后出的线性表结构,只能在表尾(栈顶)进行插入、删除操作。例如软件中的撤销操作(先操作的后恢复,后操作的先恢复)、浏览器页面的后退按钮(先打开的后访问到,后打开的先访问到),我们把允许插入和删除的一端称为栈顶,另一端称为栈底,插入操作称为入栈,删除操作称为出栈
定义说栈是一种线性表,它其实是一种特殊的线性表,它限制了插入、删除的位置


二:栈的顺序存储结构

用一段地址连续的存储单元依次存储栈中的数据元素
我们可以定义一个top变量来指示栈顶元素的下标位置,top默认为-1表示是空栈,若入栈一个元素则top++,当top+1等于存储栈元素数组的长度时,表示栈已满
数据结构(三)——栈_第1张图片
栈的顺序存储结构在插入、删除数据时,时间复杂度都是O(1),在读取数据时,时间复杂度也是O(1),但是需要预先分配内存空间


三:栈的链式存储结构

引言:栈的顺序存储结构在插入、删除数据时,时间复杂度都是O(1),其实已经很方便了,但是它需要事先确定存储元素的数组的大小,万一不够用了,还需要通过编程手段进行扩容,所以引出了栈的链式存储结构(链栈)

因为栈只能在栈顶进行插入、删除的操作,所以可以让栈顶始终在链表的头部,这样的话头指针就没有什么意义了,可以与栈顶指针合二为一,又因为头指针没有了意义,所以对于链栈来说,头结点也是不需要的
数据结构(三)——栈_第2张图片
栈的链式存储结构与顺序存储结构相同,在插入、删除数据时,时间复杂度都是O(1),但是在读取数据时,时间复杂度是O(n),栈的链式存储结构的优点是不需要预先分配内存空间大小


四:栈的应用

——递归:我们把一个直接调用自己的函数称为递归函数
说到递归就不得不说著名的斐波那契数列了(1,1,2,3,5,8,13,21,34,55,89.....)
1.下面这种方式的实现是通过迭代,迭代是使用循环结构
数据结构(三)——栈_第3张图片
2.下面这种方式的实现是通过递归,递归是使用选择结构
数据结构(三)——栈_第4张图片
因为递归的过程就是得到之前过程中的数据,并且是以倒序的顺序得到,所以利用了栈的结构

 


——四则运算表达式求值
例如求9+(3-1)*3+10/2,这种我们平时接受的标准写法叫做中缀表达式,但是计算机运算时会很麻烦,所以波兰的逻辑学家想出了一种叫做逆波兰的表示法,称为后缀表达式,用后缀表达式应该写成:9 3 1 - 3 * + 10 2 / +,把所有的符号都写在要运算数字的后面,依次把每个数字和符号都入栈,当遇到符号时,就依次取出栈顶元素两次,进行数学运算后再入栈,直到栈为空为止


五:实现栈的顺序存储结构(顺序栈)

using System;

//顺序栈类
public class Stack
{
    //存储顺序栈中元素的数组
    private T[] array;

    //栈顶元素的下标
    private int top = -1;

    //顺序栈中元素的个数
    public int Count
    {
        get
        {
            return top + 1;
        }
    }

    //构造器初始化
    public Stack()
    {
        array = new T[0];
    }
    public Stack(int size)
    {
        array = new T[size];
    }

    //判断顺序栈是否已满
    private bool IsFull()
    {
        return top + 1 == array.Length;
    }

    //判断顺序栈是否为空
    public bool IsEmpty()
    {
        return top == -1;
    }

    //清空顺序栈
    public void Clear()
    {
        top = -1;
    }

    //入栈
    public void Push(T item)
    {
        if (IsFull())
        {
            throw new Exception("栈当前已满");
        }
        else
        {
            top++;
            array[top] = item;
        }
    }

    //出栈
    public T Pop()
    {
        if (!IsEmpty())
        {
            T temp = array[top];
            top--;
            return temp;
        }
        else
        {
            throw new Exception("栈当前为空");
        }
    }

    //得到栈顶元素
    public T Peek()
    {
        if (!IsEmpty())
        {
            return array[top];
        }
        else
        {
            throw new Exception("栈当前为空");
        }
    }
}

class Program
{
    //*****进行测试*****
    public static void Main(string[] args)
    {
        Stack myStack = new Stack(1);
        myStack.Push(10);
        myStack.Peek();
        myStack.Pop();
    }
}

六:实现栈的链式存储结构(链栈)

using System;

//结点类
public class Node
{
    //数据域
    public T Data { get; set; }

    //指针域
    public Node Next { get; set; }

    //构造器初始化
    public Node()
    {
        this.Data = default(T);
        Next = null;
    }
    public Node(T value)
    {
        this.Data = value;
        Next = null;
    }
    public Node(T value, Node next)
    {
        this.Data = value;
        this.Next = next;
    }
    public Node(Node next)
    {
        this.Next = next;
    }
}

//链栈类
public class Stack
{
    //栈顶指针
    private Node top;

    //链栈中元素的个数
    private int count = 0;
    public int Count
    {
        get
        {
            return count;
        }
    }

    //构造器初始化
    public Stack()
    {
        top = null;
    }

    //判断链栈是否为空
    public bool IsEmpty()
    {
        return top == null;
    }

    //清空链栈
    public void Clear()
    {
        count = 0;
        top = null;
    }

    //入栈
    public void Push(T item)
    {
        Node addNode = new Node(item);
        addNode.Next = top;
        top = addNode;
        count++;
    }

    //出栈
    public T Pop()
    {
        if (!IsEmpty())
        {
            Node tempNode = top;
            top = tempNode.Next;
            count--;
            return tempNode.Data;
        }
        else
        {
            throw new Exception("栈当前为空");
        }
    }

    //得到栈顶元素
    public T Peek()
    {
        if (!IsEmpty())
        {
            return top.Data;
        }
        else
        {
            throw new Exception("栈当前为空");
        }
    }
}

class Program
{
    //*****进行测试*****
    public static void Main(string[] args)
    {
        Stack myStack = new Stack();
        myStack.Push(10);
        myStack.Peek();
        myStack.Pop();
    }
}

 

你可能感兴趣的:(数据结构)