首页 > 代码库 > C#栈和队列

C#栈和队列

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

 

 

栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。

 

栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。

栈要实现的接口IStack:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackAndLine
{
    public interface IStack<T>
    {
        //求长度
        int GetLength();
        //判断栈是否为空
        bool IsEmpty();
        //清空栈
        void Clear();
        //入栈操作
        void Push(T item);
        //出栈操作
        T Pop();
        //取栈顶元素
        T GetTop();
    }
}

顺序栈:

用一片连续的存储空间来存储栈中的数据元素,这样的栈称为顺序栈。类似于顺序表,用一维数组来存放顺序栈中的数据元素。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackAndLine
{
    public class Stack<T>:IStack<T>
    {
        //顺序栈的容量
        private int maxsize;
        //数组,用于存储顺序栈中的数据元素
        private T[] data;
        //指示顺序栈的栈顶
        private int top;
        //索引器
        public T this[int Index]
        {
            get
            {
                return data[Index];
            }
            set
            {
                data[Index] = value;
            }
        }
        public int Maxsize
        {
            get
            {
                return maxsize;
            }
            set
            {
                maxsize = value;
            }
        }
        public int Top
        {
            get
            {
                return top;
            }
        }
        //构造器
        public Stack(int size)
        {
            data = new T[size];
            maxsize = size;
            top = -1;
        }

        public int GetLength()
        {
            return top + 1;
        }
        //判断是否为空
        public bool IsEmpty()
        {
            if(top==-1)
            {
                return true;
            }
            else
            {
                return false;
            }

        }
        //清空栈
        public void Clear()
        {
            top = -1;
        }
        //判断栈是否已满
        public bool IsFull()
        {
            if(top==maxsize-1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //进栈操作
        public void Push(T item)
        {
            if(IsFull())
            {
                Console.WriteLine("栈已满");
                return;
            }
            data[++top] = item;
        }
        //出栈
        public T Pop()
        {
            T temp = default(T);
            if(IsEmpty())
            {
                Console.WriteLine("栈是空的");
                return temp;
            }
            temp = data[top];
            top--;
            return temp;
        }
        //获取栈顶元素
        public T GetTop()
        {
            T temp = default(T);
            if (IsEmpty())
            {
                Console.WriteLine("栈是空的");
                return temp;
            }
            return data[top];
        }
    }
}

链栈:

栈的另外一种存储方式是链式存储,这样的栈称为链栈,链栈通常用单链表来表示,它的实现是单链表的简化。所以,链栈结点的结构与单链表的结点的结构一样。

结点类Node<T>:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackAndLine
{
    public class Node<T>
    {
        //数据域
        private T data;
        //引用域
        private Node<T> next;
        //构造器
        public Node(T val,Node<T> p)
        {
            data = val;
            next = p;
        }
        public Node(Node<T> p)
        {
            next = p;
        }
        public Node(T val)
        {
            data = val;
            next = null;
        }
        public Node()
        {
            data = default(T);
            next = null;
        }
        //数据域属性
        public T Data
        {
            get
            {
                return data;
            }
            set
            {
                data = value;
            }
        }
        //引用域属性
        public Node<T> Next
        {
            get
            {
                return next;
            }
            set
            {
                next = value;
            }
        }
    }
}

链栈类LinkStack<T>的实现如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackAndLine
{
    public class LinkStack<T>:IStack<T>
    {
        private Node<T> top;//栈顶指示器
        private int num;//栈中结点个数
        public Node<T> Top
        {
            get
            {
                return top;
            }
            set
            {
                top = value;
            }
        }
        public int Num
        {
            get
            {
                return num;
            }
            set
            {
                num = value;
            }
        }
        //构造器
        public LinkStack()
        {
            top = null;
            num = 0;
        }

        //求长度
        public int GetLength()
        {
            return num;
        }
        //判断栈是否为空
        public bool IsEmpty()
        {
            if((top==null)&&(num==0))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //清空栈
        public void Clear()
        {
            top = null;
            num = 0;
        }
        //入栈操作
        public void Push(T item)
        {
            Node<T> q = new Node<T>(item);
            if(top==null)
            {
                top = q;
            }
            else
            {
                q.Next = top;
                top = q;
            }
            num++;
        }
        //出栈操作
        public T Pop()
        {
            if(IsEmpty())
            {
                Console.WriteLine("栈是空的");
                return default(T);
            }
            Node<T> p = top;
            top = top.Next;
            num--;
            return p.Data;
        }
        //获取栈顶结点值
        public T GetTop()
        {
            if(IsEmpty())
            {
                Console.WriteLine("栈是空的");
                return default(T);
            }
            return top.Data;
        }
    }
}

队列

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

 

在队列这种数据结构中,最先插入的元素将是最先被删除的元素;反之最后插入的元素将是最后被删除的元素,因此队列又称为"先进先出"(FIFO—first in first out)的线性表。

队列要实现的接口:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackAndLine
{
    public interface IQueue<T>
    {
        //求队列长度
        int GetLength();
        //判断队列是否为空
        bool IsEmpty();
        //清空队列
        void Clear();
        //入队
        void In(T item);
        //出队
        T Out();
        //取队头元素
        T GetFront();
    }
}

顺序队列:

用一片连续的存储空间来存储队列中的数据元素,这样的队列称为顺序队列。这里用循环顺序队列来做为例子,当队尾指示器rear到达数组的上限时,如果还有数据元素入队并且数组的第0个空间空闲时,队尾指示器rear指向数组的0端。所以队尾指示器的加1操作为;

rear=(rear + 1)%maxsize

队头指示器的操作也是如此,当队头指示器front到达数组的上限时候,如果还有数据元素出队,对头指示器front指向数组的0端。所以,队头指示器的加一操作为:

front=(front + 1)%maxsize

 

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackAndLine
{
    public class Queue<T>:IQueue<T>
    {
        //循环顺序队列容量
        private int maxsize;
        //数组,用于存储循环顺序队列的数据元素
        private T[] data;
        //指示循环顺序队列的队头
        private int front;
        //指示循环顺序队列的队尾
        private int rear;
        //索引器
        public T this[int index]
        {
            get
            {
                return data[index];
            }
            set
            {
                data[index] = value;
            }
        }
        //容量属性
        public int Maxsize
        {
            get
            {
                return maxsize;
            }
            set
            {
                maxsize = value;
            }
        }
        //队头属性
        public int Front
        {
            get
            {
                return rear;
            }
            set
            {
                rear = value;
            }
        }
        public Queue(int size)
        {
            data = new T[size];
            maxsize = size;
            front = rear = -1;
        }
        //求循环队列的长度
        public int GetLength()
        {
            return (rear - front + maxsize) % maxsize;
        }
        //判断是否队列为空
        public bool IsEmpty()
        {
            if(front==rear)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //清空队列
        public void Clear()
        {
            front = rear = -1;
        }
        //判断循环队列是否满了
        public bool IsFull()
        {
            if((rear+1)%maxsize==front)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //入队
        public void In(T item)
        {
            T temp = default(T);
            if (IsFull())
            {
                Console.WriteLine("Queue is full");
                return;
            }
            data[++rear] = item;
        }
        //出队
        public T Out()
        {
            T temp = default(T);
            if(IsEmpty())
            {
                Console.WriteLine("Queue is empty");
                return temp;
            }
            temp = data[++front];
            return temp;
        }
        //获取队头数据元素
        public T GetFront()
        {
            if(IsEmpty())
            {
                Console.WriteLine("Queue is empty");
                return default(T);
            }
            return data[front + 1];
        }
    }
}

 

 

链队列:

队列的另外一种存储方式是链式存储,这样的队列称为链队列,同栈一样,链队列通常用单链表表示

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackAndLine
{
    public class LinkQueue<T>:IQueue<T>
    {
        private Node<T> front;//队列头指示器
        private Node<T> rear;//队列尾指示器
        private int num;//队列结点个数
        public Node<T> Front
        {
            get
            {
                return front;
            }
            set
            {
                front = value;
            }
        }
        public Node<T> Rear
        {
            get
            {
                return rear;
            }
            set
            {
                rear = value;
            }
        }
        public int Num
        {
            get
            {
                return num;
            }
            set
            {
                num = value;
            }
        }
        public LinkQueue()
        {
            front = rear = null;
            num = 0;
        }
        //求链队列长度
        public int GetLength()
        {
            return num;
        }
        //判断是否为空
        public bool IsEmpty()
        {
            if((front==rear)&&(num==0))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //清空队列
        public void Clear()
        {
            front = rear = null;
            num = 0;
        }

        public void In(T item)
        {
            Node<T> q = new Node<T>(item);
            if(rear==null)
            {
                rear = q;
            }
            else
            {
                rear.Next = q;
                rear = q;
            }
            num++;
        }
        //出队
        public T Out()
        {
            if(IsEmpty())
            {
                Console.WriteLine("队列是空的");
                return default(T);
            }
            Node<T> p = front;
            front = front.Next;
            if(front==null)
            {
                rear = null;
            }
            num--;
            return p.Data;
        }
        //获取链队列头结点的值
        public T GetFront()
        {
            if(IsEmpty())
            {
                Console.WriteLine("队列是空");
                return default(T);
            }
            return front.Data;
        }
    }
}

最后附上项目的源码:http://files.cnblogs.com/xmfdsh/CSharp%E6%A0%88%E5%92%8C%E9%98%9F%E5%88%97.rar