C#数据结构_栈和队列

:先进后出,只能在栈顶进行操作。

栈的操作主要包括在栈顶插入元素和删除元素、取栈顶元素和判断栈是否为空等。

栈的接口定义:

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

 字段 top 表示栈顶,top 的范围是0 到 maxsize-1,如果顺序栈为空,top=-1

顺序栈类 SeqStack<T>的实现:

    public class SeqStack<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 SeqStack(int size)
        {
            data = new T[size];
            maxsize = size;
            top = -1;
        }
        //求栈的长度
        public int GetLength()
        {
            return top + 1;
        }
        //清空顺序栈
        public void Clear()
        {
            top = -1;
        }
        //判断顺序栈是否为空
        public bool IsEmpty()
        {
            if (top == -1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //判断顺序栈是否为满
        public bool IsFull()
        {
            if (top == maxsize - 1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //入栈
        public void Push(T item)
        {
            if (IsFull())
            {
                return;
            }
            data[++top] = item;
        }
        //出栈
        public T Pop()
        {
            T tmp = default(T);
            if (IsEmpty())
            {
                return tmp;
            }
            tmp = data[top];
            --top;
            return tmp;
        }
        //获取栈顶元素
        public T GetTop()
        {
            if (IsEmpty())
            {
                return default(T);
            }
            return data[top];
        }
    }
SeqStack

链栈 通常用单链表来表示,栈顶设在链表的头部,并且不需要头结点
链栈结点类(Node<T>)的实现:

    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;
        }
        //数据域属性
        public T Data
        {
            get { return data; }
            set { data = value; }
        }
        //引用域
        public Node<T> Next
        {
            get { return next; }
            set { next = value; }
        }
    }
Node

链栈类 LinkStack<T>的实现: LinkStack<T>类增 设一个字段 num 表示链栈中结点的个数。

    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 void Clear()
        {
            top = null;
            num = 0;
        }
        //判断链栈是否为空
        public bool IsEmpty()
        {
            if ((top == null) && (num == 0))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //入栈
        public void Push()
        {
            Node<T> q = new Node<T>(item);
            if (top == null)
            {
                top = q;
            }
            else
            {
                q.Next = top;
                top = q;
            }
            ++num;
        }
        //出栈
        public T Pop()
        {
            if (IsEmpty())
            {
                return default(T);
            }
            Node<T> p = top;
            top = top.Next;
            --num;
            return p.Data;
        }
        //取栈顶结点的值
        public T GetTop()
        {
            if (IsEmpty())
            {
                return default(T);
            }
            return top.Data;
        }
    }
LinkStack

 进制转换:将一个十进制数 N 转换为八进制数:利用辗转相 除法,转换得到的八进制数各个数位

 算法思想如下:当 N>0 时,重复步骤 1 和步骤 2。

步骤 1:若 N≠0,则将 N%8 压入栈中,执行步骤 2;若 N=0。则将栈的内 容依次出栈,算法结束。

步骤 2:用 N/8 代替 N,返回步骤 1。

算法实现如下:

  public void Conversion(int n)
    {
        LinkStack<int> s = new LinkStack<int>();
        while(n > 0)
        {
            s.Push(n%8);//余数入栈
            n = n/8;
        }
        while(!s.IsEmpty())
        {
            n = s.Pop();
        }
    }

括号匹配

算法思想:如果括号序列不为空,重复步骤 1。

步骤 1:从括号序列中取出 1 个括号,分为三种情况:

a)    如果栈为空,则将括号入栈;

b)    如果括号与栈顶的括号匹配,则将栈顶括号出栈。

c)    如果括号与栈顶的括号不匹配,则将括号入栈。

步骤 2:如果括号序列为空并且栈为空则括号匹配,否则不匹配。

用顺序栈实现算法:

    public bool MatchBracket(char[] charlist)
    {
        SeqStack<char> s = new SeqStack<char>(50);
        int len = charlist.Length;
        for (int i = 0; i < len; ++i)
        {
            if (s.IsEmpty())
            {
                s.Push(charlist[i]);
            }
            else if(((s.GetTop()=="(")&&(charlist[i]==")")))||(s.GetTop()=="[" && charlist[i]=="]"))
            {
                s.Pop();
            }
            else
            {
                s.Push(charlist[i]);
            }
        }
 
        if (s.IsEmpty())
        {
            return true;
        }
        else
        {
            return false;
        }
    }
MatchBracket(char[] charlist)

 队列(Queue)是插入操作限定在表的尾部,其它操作限定在表的头部进行的线性表。

队列的操作主要包括:在队尾插入元素、在队头删除元素、取队头元素和判断队列是否为空等。

 队列“队尾入 队头出”的操作造成“假溢出”,解决假溢出的方法:将顺序队列看成是首尾相接的循环结构,头尾指示器的关系不变,这种队列叫循环顺序队列。

 front 表示队头,front 的范围是 0 到 maxsize-1。 rear 表示队尾,rear 的范围也是 0 到 maxsize-1。

如果循环顺序队列为空,front=rear=-1。 当执行入队列操作时需要判断循环顺序队列是否已满。

如果循环顺序队列已满, (rear  +  1)  %  maxsize==front ,循环顺序队列已满不能插入元素。

求循环队列中数据元素的个数:(rear-front+maxsize)%maxsize

 循环顺序队列类 CSeqQueue<T>的实现:

public class CSeqQueue<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 front; }
            set { front = value; }
        }
        //队尾属性
        public int Rear
        {
            get { return rear; }
            set { rear = value; }
        }
        //构造器
        public CSeqQueue(int size)
        {
            data = new T[size];
            maxsize = size;
            front = rear = -1;
        }
        //求循环队列长度
        public int GetLength()
        {
            return (rear - front + maxsize) % maxsize;
        }
        //清空循环队列
        public void Clear()
        {
            front = rear = -1;
        }
        //判断循环队列是否为空
        public bool IsEmpty()
        {
            if (front == rear)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //判断循环顺序队列是否为满
        public bool IsFull()
        {
            if ((rear + 1) % maxsize == front)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //入队
        public void In(T item)
        {
            if (IsFull())
            {
                return;
            }
            else
            {
                data[++rear] = item;
            }
        }
        //出队
        public T Out()
        {
            T tmp = default(T);
            if (IsEmpty())
            {
                return tmp;
            }
            tmp = data[++front];
            return tmp;
        }
        //获取队头数据元素
        public T GetFront()
        {
            if (IsEmpty())
            {
                return default(T);
            }
            return data[++front];
        }
    }
CSeqQueue

链队列

队列结点类(Node<T>)的实现:

    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; }
        }
    }
Node

链队列类 LinkQueue<T>的实现:

    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 int Rear
        {
            get { return rear; }
            set { rear = value; }
        }
        //结点的个数
        public int Num
        {
            get{return num;}
            set{num=value;}
        }
        //构造器
        public LinkQueue(int size)
        {
            front=rear=-1;
            num=0;
        }
        //求循环队列长度
        public int GetLength()
        {
            return num;
        }
        //清空循环队列
        public void Clear()
        {
            front = rear = null;
            num=0;
        }
        //判断循环队列是否为空
        public bool IsEmpty()
        {
            if (front == rear)&&(num==0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //入队
        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())
            {
                return default(T);
            }
            Node<T> p = front;
            front = front.Next;
            if(front == null)
            {
                rear=null;
            }
            --num;
            return p.Data;
        }
        //获取队头数据元素
        public T GetFront()
        {
            if (IsEmpty())
            {
                return default(T);
            }
            return front.Data;
        }
    }
LinkQueue

判断一个字符串是否是回文:采用循环顺序队列和顺序栈 来实现

    public bool Main()
    {
        SeqStack<char> s = new SeqStack<char>(50); 
        CSeqQueue<char> q = new CSeqQueue<char>(50); 
        string str = Console.ReadLine();
        for(int i = 0; i < str.Length; ++i)
        {
            s.Push(str[i]);
            q.In(str[i]);
        }
        while(!s.IsEmpty() && !q.IsEmpty())
        {
            if(s.Pop() != q.Out())
            {
                return false;
            }
         }
         return true;
    }

转载于:https://www.cnblogs.com/shirln/p/8761856.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值