C#栈

114 阅读3分钟

栈和队列

栈和队列也是线性结构,线性表、栈和队列这三种数据结构的数据元素以及数据元素间的逻辑关系完全相同,差别是线性表的操作不受限制,而栈和队列的操作受到限制。栈的操作只能在表的一端进行,队列的插入操作在表的一端进行,而其他操作在表的另一端进行,所以,把栈和队列称为操作受限的线性表。

操作限定在表的尾端进行的线性表,表尾称为栈顶(Top),另一端是固定的,叫栈底(Bottom)。当栈中没有数据元素时叫空栈(Empty Stack)。

栈通常记为:S=(a1,a2...,an),a1为栈底元素,an为栈顶元素。a1第一个入栈,an最后一个入栈,出栈时相反,an第一个出栈,a1最后一个出栈,遵循先进后出或后进先出的原则。

BCL中的栈

C#2.0以下版本只提供了非泛型的Stack类(存储Object类型)

C#2.0开始提供泛型的Stack类

重要方法如下:

  • Push() 入栈,添加数据
  • Pop() 出栈,删除数据,返回被删除的数据
  • Peek() 取得栈顶的数据,不删除
  • Clear() 清空所有数据
  • Count() 取得栈中数据的个数

栈的接口

public interface IStackDS<T>
    {
        int Count { get; }//get data number
        int GetLength();
        bool IsEmpty();
        void Clear();
        void Push(T item);
        T Pop();
        T Peek();
    }

顺序栈

用一片连续的存储空间来存储栈中的数据元素(使用数组),类似于顺序表。

栈顶指示器top设在数组下标为0的端,top随着插入和删除而变化,当栈为空时,top=-1。

顺序栈的实现
 public class SeqStack<T>:IStackDS<T>
    {
        private T[] data;
        private int top;

        public SeqStack(int size)
        {
            data = new T[size];
            top = -1;
        }

        public SeqStack():this(10)
        {
        }

        public int Count
        {
            get
            {
                return top + 1;
            }
        }
        public int GetLength()
        {
            return Count;
        }

        public bool IsEmpty()
        {
            return Count == 0;
        }

        public void Clear()
        {
            top = -1;
        }

        public void Push(T item)
        {
            data[top + 1] = item;
            top++;
        }

        public T Pop()
        {
            T temp = data[top];
            top--;
            return temp;
        }

        public T Peek()
        {
            return data[top];
        }
    }

链栈

链栈(Linked Stack),链栈通常用单链表来表示,它的实现是单链表的简化。由于链栈的操作只在一端进行,为了操作方便,把栈顶设在链表的头部,并且不需要头节点。

链栈节点
public class Node<T>
    {
        //链栈的节点
        
        private T data;
        private Node<T> next;

        public Node()
        {
            data = default(T);
            next = null;
        }

        public Node(T data)
        {
            this.data = data;
            next = null;
        }

        public Node(T data,Node<T> next)
        {
            this.data = data;
            this.next = next;
        }

        public Node(Node<T> next)
        {
            this.next = next;
            data = default(T);
        }
        
        public T Data
        {
            get { return data; }
            set { data = value; }
        }

        public Node<T> Next
        {
            get { return next; }
            set { next = value; }
        }
    }
链栈的实现
public class LinkStack<T>:IStackDS<T>
    {
        private Node<T> top;//栈顶元素节点
        private int count = 0;//栈中元素的个数

        //取得栈中元素的个数
        public int Count
        {
            get { return count; }
        }
        
        //取得栈中元素的个数
        public int GetLength()
        {
            return count;
        }
        
        //判断栈是否为空
        public bool IsEmpty()
        {
            return count == 0;
        }

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

        //入栈
        public void Push(T item)
        {
            //把新添加的元素作为头节点(栈顶)。
            Node<T> newNode = new Node<T>(item);
            newNode.Next = top;
            top = newNode;
            count++;
        }

        //出栈
        public T Pop()
        {
            //取得栈顶元素,然后删除
            T data = top.Data;
            top = top.Next;
            count--;
            return data;
        }

        //取得栈顶数据,不删除栈顶
        public T Peek()
        {
            return top.Data;
        }
    }