数据结构复习--栈和队列(1)--栈
1.栈和队列简介:
栈和队列是非常重要的两种数据结构,在软件设计中应用很多。栈和队列也是线性结构,线性表,栈和队列这三种数据元素和数据元素间的逻辑完全相同。差别是线性表的操作不受限制,而栈和队列的操作收到限制,栈的操作只能在表的一端进行,队列的插入操作在表的一端进行而其它操作在表的另一端进行,所以把栈和队列称为操作受限的线性表
栈:
栈(Stack)是操作限定在表的尾端进行的线性表。表尾由于要进行插入,删除等操作,所以,它具有特殊含义,把表尾成为栈顶(Top),另一端是固定的,叫栈底(Bottom)。当栈中没有数据元素时叫空栈(Empty Stack)。
栈通常记为S=(a1,a2,......an),a1为栈底元素,an为栈订元素,这n个数据元素按照a1,a2,......an的顺序依次入栈,而出栈的顺序相反,an第一个出栈,a1最后一个出栈。所以,栈的操作是按照后进先出(Last In First Out)或先进后出(First In Last Out)。栈操作示意图:
C#2.0中提供了泛型的Stack<T>类,用来进行栈的操作。
常用方法:
1.Push() 入栈,添加数据
2.Pop() 出栈,删除数据并返回被删除的数据
3.Peek()取得栈订的数据,不删除
4.Clear()清空所有的数据
4.Count 取得栈中数据的个数
2.顺序栈:
用一片连续的存储空间来存储栈中的数据元素,这样的栈成为顺序栈<Sequence Stack>,类似于顺序表,用以为数组来存放栈中的数据元素。栈顶指示器top设在数组下标为0的一端,top随插入和删除而变化,当栈顶为空时,top=-1 示意图:
c#实现顺序栈:
public class SeqStack<T> : IStackDS<T> { /// <summary> /// 存放元素 /// </summary> private T[] Data; /// <summary> /// 指向栈顶索引 /// </summary> private int top; /// <summary> /// 构造函数 /// </summary> /// <param name="size">长度</param> public SeqStack(int size) { Data = new T[size]; top = -1; } /// <summary> /// 默认构造函数 /// </summary> public SeqStack() : this(10) { } /// <summary> /// 获取元素数量 /// </summary> public int Count { get { return top + 1; } } /// <summary> /// 清空 /// </summary> public void Clear() { top = -1; } /// <summary> /// 获取长度 /// </summary> /// <returns></returns> public int GetLength() { return Count; } /// <summary> /// 是否为空 /// </summary> /// <returns></returns> public bool IsEmpty() { return Count == 0; } /// <summary> /// 获取栈顶元素 /// </summary> /// <returns></returns> public T Peek() { return Data[top]; } /// <summary> /// 出栈 /// </summary> /// <returns></returns> public T Pop() { T temp = Data[top]; top--; return temp; } /// <summary> /// 入栈 /// </summary> /// <param name="item"></param> public void Push(T item) { Data[top + 1] = item; top++; } }
3.链栈:
栈的另外一种存储方式是链式存储,这样的栈成为链栈(Linked Stack)。链栈通常用单链表来表示,它的实现是单链表的简化。所以链栈的结点结构与单链表一样。由于链栈的操作只在一端进行,为了操作方便,把栈顶设在链表的头部,并且不需要头结点。
c#实现链栈:
class LinkStack<T> : IStackDS<T> { /// <summary> /// 栈顶元素结点 /// </summary> private Node<T> top; /// <summary> /// 栈中元素个数 /// </summary> private int count = 0; /// <summary> /// 取得栈中元素个数 /// </summary> public int Count { get { return count; } } /// <summary> /// 清空栈中数据 /// </summary> public void Clear() { count = 0; top = null; } /// <summary> /// 取得栈中元素个数 /// </summary> /// <returns></returns> public int GetLength() => count; /// <summary> /// 是否为空 /// </summary> /// <returns></returns> public bool IsEmpty() => count == 0; /// <summary> /// 取得栈顶元素数据 不删除栈顶 /// </summary> /// <returns></returns> public T Peek() { return top.Data; } /// <summary> /// 出栈 /// </summary> /// <returns></returns> public T Pop() { //取得栈顶元素,删除 T data = top.Data; top = top.Next; count--; return data; } /// <summary> /// 入栈 /// </summary> /// <param name="item"></param> public void Push(T item) { //把新添加的元素作为栈顶 Node<T> newNode = new Node<T>(item); newNode.Next = top; top = newNode; count++; } }
结点类:
public class Node<T> { /// <summary> /// 存放数据 /// </summary> private T data; /// <summary> /// 下一个结点 /// </summary> private Node<T> next; #region 构造函数 public Node() { data = default(T); next = null; } public Node(T data) { this.data = data; next = null; } public Node(T _data,Node<T> _next) { data = _data; next = _next; } public Node(Node<T> _next) { data = default(T); next = _next; } #endregion public T Data { get => data; set => data = value; } public Node<T> Next { get => next; set => next = value; } }