• 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;
        }
  • 相关阅读:
    linux execl()函数 关于execl()函数族的用法不在赘述,
    mysql日期格式化
    JavaScript超越了Java,c,python等等成为Stack Overflow上最热门的
    GO语言web框架Gin之完全指南
    计算机专业四年本科的课程表是什么样的?
    文化常识大全201901 普通老百姓交的朋友谓“布衣之交”
    JavaScript超越了Java,c,python等等成为Stack Overflow上最热门的
    linux bash吧,还有啥Bourne Again Shell
    TCP、UDP服务器模型 在网络程序里面,通常都是一
    SpringMVC常见面试题总结(超详细回答)
  • 原文地址:https://www.cnblogs.com/shirln/p/8761856.html
Copyright © 2020-2023  润新知