精华内容
下载资源
问答
  • 数据结构-基本算法-顺序(学生时代源码,调试可运行)
  • 数据结构与算法和队列)

    千次阅读 2020-01-11 21:38:29
    首语 历经一个月的时间,自己...接下来我们开始第二节的数据结构学习,和队列。 是限定仅在表尾进行插入和删除操作的线性表。 允许插入和删除的一端称为栈顶(top),另一端称为底(bottom),不含任...

    首语

    • 历经一个月的时间,自己终于搭建完成了个人网站,还在持续优化中,网站采用halo博客系统,功能非常强大!欢迎大家来我的网站逛逛。有什么建议可以留言!

    网站地址:http://www.yanghujun.com

    • 接下来我们开始第二节的数据结构学习,栈和队列。

    • 栈是限定仅在表尾进行插入和删除操作的线性表。
    • 允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出 的线性表。
      在这里插入图片描述

    栈的顺序存储结构

    • 如用数组实现,栈底是:下标为0的一端。
      在这里插入图片描述

    栈的链式存储结构

    在这里插入图片描述

    链栈的出入栈操作

    • 链栈的入栈操作
      在这里插入图片描述
    s->data=e;
    s->next=stack->top;
    stack->top=s;
    stack->count++;
    
    • 链栈的出栈操作

    在这里插入图片描述

    p=stack->top
    stack->top=p->next;
    free(p)
    stack->count--;
    

    栈的经典实用(逆波兰表达式法)

    • 标准四则运算表达式——中缀表达式
      9+(3-1)*3+10/2
    • 计算机采用——后缀表达式
      9 3 1 - 3 * + 10 2 / +
      在这里插入图片描述
    中缀表达式转后缀表达式

    数字输出,运算符进栈,括号匹配出栈,栈顶优先级低出栈。

    在这里插入图片描述

    代码实现

    • 中缀表达式->后缀表达式
    /**
         * @param expression 逆波兰表达式
         * 数字输出,运算符进栈,括号匹配出栈,栈顶优先级低出栈
         * @return 后缀式链表
         */
        public static LinkedList<String> parse(String expression) {
            // 结果输出栈
            LinkedList<String> output = new LinkedList<>();
            // 运算符栈
            Stack<Character> operators = new Stack<>();
            // 字符串截取起始位置
            int startPos = 0;
            // 字符串截取末尾位置
            int endPos = 0;
            // 正序遍历表达式中的每一个字符c
            for (char c : expression.toCharArray()) {
                // 字符串截取的结束位置+1
                ++endPos;
                // 判断字符c是否为运算符。
                if (isOperator(c)) {
                    // 若运算符c之前有可保存的信息则将其作为一个整体保存至output链表。
                    if (startPos < endPos - 1)
                        output.add(expression.substring(startPos, endPos - 1));
                    // 更新字符串截取的起始位置
                    startPos = endPos;
                    // 若运算符c为左括号"(",则直接存入运算符栈。
                    if (c == '(') {
                        operators.push(c);
                        // 若运算符c为右括号")",则依次从运算符栈中弹出运算符并保存至output链表,直到遇到左括号为止。
                    } else if (c == ')') {
                        char op;
                        while (!operators.isEmpty() && (op = operators.pop()) != '(') {
                            output.add(String.valueOf(op));
                        }
                        // 若运算符c为非括号运算符(即:四则运算符号)
                    } else {
    
                        // 若运算符栈为空则直接将c压栈至运算符栈。
                        if (operators.isEmpty()) {
                            operators.push(c);
                            // 若运算符栈栈顶的运算符为左括号,则将c直接压栈至运算符栈。
                        } else if (operators.peek() == '(') {
                            operators.push(c);
                            // 若运算符c的优先级高于运算符栈栈顶的运算符优先级,则将c压栈至运算符栈。
                        } else if (getOperatorPriorityValue(c) > getOperatorPriorityValue(operators.peek())) {
                            operators.push(c);
                            // 若运算符c的优先级小于或等于运算符栈栈顶的运算符优先级,则依次从运算符栈中弹出运算符并保存至output链表,直到遇到左括号或c的优先级高于栈顶运算符优先级的为止。再将c压栈至运算符栈。
                        } else {
                            while (!operators.isEmpty() && getOperatorPriorityValue(c) <= getOperatorPriorityValue(operators.peek()) && operators.peek() != '(') {
                                output.add(String.valueOf(operators.pop()));
                            }
                            operators.push(c);
                        }
                    }
                }
            }
    
            // 当表达式遍历完成后,将尚未保存的非运算符信息作为整体保存至output链表。若运算符栈中尚有运算符时,则依序弹出运算符到output链表。
            if (startPos < expression.length()) output.add(expression.substring(startPos));
            while (!operators.isEmpty()) {
                output.add(String.valueOf(operators.pop()));
            }
            return output;
        }
    
     // 运算符
        private final static char[] OP = new char[]{'+', '-', '*', '/', '(', ')'};
        /**
         * 判断字符是否是运算符
         * @param op 运算符
         * @return 是运算符返回true,不是则返回false
         */
        public static boolean isOperator(char op) {
            for (int i = 0; i < OP.length; ++i) {
                if (op == OP[i])
                    return true;
            }
            return false;
        }
    	/**
         * 获取运算符优先等级
         * @param op 运算符
         * @return 根据OP数组中运算符的顺序计算出运算符的优先等级:+ -是0级,* /是1级,( )是2级
         */
        public static int getOperatorPriorityValue(char op) {
            return (String.copyValueOf(OP).indexOf(op)) / 2;
        }
    
    
    • 后缀表达式计算
    /**
         * 表达式计算
         * 先将中缀表达式转换为后缀表达式,再计算表达式的结果
         * @param expression 表达式
         * @return 运算结果
         */
        public static double operation(String expression) {
    
            // 使用逆波兰算法处理
            LinkedList<String> rpnList = RPN.parse(expression);
    
            // 保存每一步运算结果的操作数栈
            Stack<Double> operands = new Stack<>();
    
            // 若表达式第一位为运算符,则表达式无效
    
    
            // 遍历逆波兰表达式中每一项元素
            for (String elem : rpnList) {
    
                // 若是运算符
                if (RPN.isOperator(elem.charAt(0))) {
    
    
                    // 从操作数栈取出栈顶的两个操作数
                    double value2 = operands.pop();
                    double value1 = operands.pop();
    
                    // 获得运算结果
                    double result = binaryOperation(elem.charAt(0), value1, value2);
    
                    // 将计算结果压栈
                    operands.push(result);
    
                    // 如果是数值
                } else {
                    operands.push(Double.parseDouble(elem));
                }
            }
    
            // 返回操作数栈中唯一的元素
            return operands.pop();
        }
      /**
         * 二元运算
         * @param operator 运算符
         * @param value1   值1
         * @param value2   值2
         * @return 运算结果
         */
        private static double binaryOperation(char operator, double value1, double value2) {
            switch (operator) {
                case '+':
                    return value1 + value2;
                case '-':
                    return value1 - value2;
                case '*':
                    return value1 * value2;
                case '/':
                    if (value2 == 0) throw new ArithmeticException("/ by zero.");
                    return value1 / value2;
                default:
                    throw new RuntimeException("");
            }
        }
    

    栈(Stack)源码

    /**
         * Pushes an item onto the top of this stack. This has exactly
         * the same effect as:
         * <blockquote><pre>
         * addElement(item)</pre></blockquote>
         * @param   item   the item to be pushed onto this stack.
         * @return  the <code>item</code> argument.
         * @see     java.util.Vector#addElement
         */
        public E push(E item) {
            addElement(item);
            return item;
        }
     /**
         * Adds the specified component to the end of this vector,
         * increasing its size by one. The capacity of this vector is
         * increased if its size becomes greater than its capacity.
         * <p>This method is identical in functionality to the
         * {@link #add(Object) add(E)}
         * method (which is part of the {@link List} interface).
         * @param   obj   the component to be added
         */
        public synchronized void addElement(E obj) {
            modCount++;
            ensureCapacityHelper(elementCount + 1);
            elementData[elementCount++] = obj;
        }
    /**
         * This implements the unsynchronized semantics of ensureCapacity.
         * Synchronized methods in this class can internally call this
         * method for ensuring capacity without incurring the cost of an
         * extra synchronization.
         * @see #ensureCapacity(int)
         */
        private void ensureCapacityHelper(int minCapacity) {
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
        private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                             capacityIncrement : oldCapacity);
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    
    /**
         * Removes the object at the top of this stack and returns that
         * object as the value of this function.
         * @return  The object at the top of this stack (the last item
         *          of the <tt>Vector</tt> object).
         * @throws  EmptyStackException  if this stack is empty.
         */
        public synchronized E pop() {
            E       obj;
            int     len = size();
            obj = peek();
            removeElementAt(len - 1);
            return obj;
        }
         /**
         * Deletes the component at the specified index. Each component in
         * this vector with an index greater or equal to the specified
         * {@code index} is shifted downward to have an index one
         * smaller than the value it had previously. The size of this vector
         * is decreased by {@code 1}.
         * <p>The index must be a value greater than or equal to {@code 0}
         * and less than the current size of the vector.
         * <p>This method is identical in functionality to the {@link #remove(int)}
         * method (which is part of the {@link List} interface).  Note that the
         * {@code remove} method returns the old value that was stored at the
         * specified position.
         * @param      index   the index of the object to remove
         * @throws ArrayIndexOutOfBoundsException if the index is out of range
         *         ({@code index < 0 || index >= size()})
         */
        public synchronized void removeElementAt(int index) {
            modCount++;
            if (index >= elementCount) {
                throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                         elementCount);
            }
            else if (index < 0) {
                throw new ArrayIndexOutOfBoundsException(index);
            }
            int j = elementCount - index - 1;
            if (j > 0) {
                System.arraycopy(elementData, index + 1, elementData, index, j);
            }
            elementCount--;
            elementData[elementCount] = null; /* to let gc do its work */
        }
    
    /**
         * Looks at the object at the top of this stack without removing it
         * from the stack.
         *
         * @return  the object at the top of this stack (the last item
         *          of the <tt>Vector</tt> object).
         * @throws  EmptyStackException  if this stack is empty.
         */
        public synchronized E peek() {
            int     len = size();
    
            if (len == 0)
                throw new EmptyStackException();
            return elementAt(len - 1);
        }
        /**
         * Returns the component at the specified index.
         * <p>This method is identical in functionality to the {@link #get(int)}
         * method (which is part of the {@link List} interface).
         * @param      index   an index into this vector
         * @return     the component at the specified index
         * @throws ArrayIndexOutOfBoundsException if the index is out of range
         *         ({@code index < 0 || index >= size()})
         */
        public synchronized E elementAt(int index) {
            if (index >= elementCount) {
                throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
            }
            return elementData(index);
        }
    

    队列

    • 队列是只允许在一端进行插入操作、而在另一端进行删除操作的线性表!
    • 插入的一端称为队尾,删除的一端称为队头。

    队列的顺序存储

    • 缺点
      1.出队复杂度高o(n)
      2.容易假溢出。
      在这里插入图片描述
      在这里插入图片描述

    循环队列

    • 把队列的这种头尾相接的顺序存储结构称为循环队列。
      在这里插入图片描述

    队列的连式存储及结构模式

    • 队列的链式存储结构,其实就是线性表的单链表,只不过是它只能尾进头出而已。
      在这里插入图片描述
    • 空队列
      在这里插入图片描述

    队列(Queue)源码

    /**
         * Appends the specified element to the end of this Vector.
         * @param e element to be appended to this Vector
         * @return {@code true} (as specified by {@link Collection#add})
         * @since 1.2
         */
        public synchronized boolean add(E e) {
            modCount++;
            ensureCapacityHelper(elementCount + 1);
            elementData[elementCount++] = e;
            return true;
        }
        /**
         * This implements the unsynchronized semantics of ensureCapacity.
         * Synchronized methods in this class can internally call this
         * method for ensuring capacity without incurring the cost of an
         * extra synchronization.
         *
         * @see #ensureCapacity(int)
         */
        private void ensureCapacityHelper(int minCapacity) {
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    
    展开全文
  • 数据结构与算法详解

    千次阅读 多人点赞 2019-08-13 18:51:04
    目录什么是设计介绍数组实现结构设计push插入s 什么是 百度百科上,是这么定义的: (stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地...

    什么是栈

    在这里插入图片描述
    百度百科上,栈是这么定义的:

    • 栈(stack)又名堆栈,它是一种运算受限线性表。限定仅在表尾进行插入删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

    稍微介绍一下关键名词:

    • 运算受限:也就是这个表你不能随便的删除插入。只能按照它的规则进行插入删除。比如栈就只能在一端就行插入和删除。同样,队列也是运算受限,只能在两天操作。
    • 线性表:栈也是一种线性表,前面详细介绍过线性表,它表达的是一种数据的逻辑关系。也就是在栈内各个元素是相邻的。当然在具体实现上也分数组和链表实现,他们的物理存储结构不同。但是逻辑结构(实现的目的)相同。
    • 栈顶栈底: 这个描述是偏向于逻辑上的内容,因为大家知道数组在末尾插入删除更容易,而单链表通常在头插入删除更容易。所以数组可以用末尾做栈顶,而链表可以头做栈顶。

    在这里插入图片描述

    栈的应用:

    • 栈的应用广泛,比如你的程序执行查看调用堆栈、加减运算、甚至在搜索算法中dfs,替代递归等等。所以栈也是必须掌握的一门数据结构。很多规范也是栈,比如上图放书拿书一样!

    设计与介绍

    这里我们介绍数组实现的栈和链表实现的栈。

    数组实现

    结构设计

    • 对于数组来说,我们模拟栈的过程很简单,因为栈是后进先出,我们很容易在数组的末尾进行插入和删除。所以我们选定末尾为栈顶。所以对于一个栈所需要的基础元素是 一个data数组和一个top(int)表示栈顶位置。
    • 那么初始话以及构造的函数代码为:
    private T data[];
    private int top;
    public seqStack() {
    	data=(T[]) new Object[10];
    	top=-1;
    }
    public seqStack(int maxsize)
    {
    	data=(T[]) new Object[maxsize];
    	top=-1;
    }
    

    push插入

    栈的核心操作之一push:入栈操作。

    • 如果top<数组长度-1。入栈。top++;a[top]=value;
    • 如果top==数组长度-1;栈满。
      在这里插入图片描述

    pop弹出并返回首位

    • 如果top>=0,栈不为空,可以弹出。return data[top--];
    • 如下图,本来栈为1,2,3,4(栈顶),执行pop操作。top变为3的位置并且返回4;
      在这里插入图片描述

    其他操作

    • 其他例如peek操作时返回栈顶不弹出.所以只需满足题意时候return data[top]即可。

    链表实现

    有数组实现,链表当然也能实现。对于栈的运算。大致可以分为两种思路:

    • 像数组那样在尾部插入删除。大家都知道链表效率低在查询。而查询到尾部效率很低。而我们就算用了尾指针,可以解决尾部插入效率。但是依然无法解决删除效率(删除需要找到前节点).还需要双向链表。前面虽然详细介绍过双向链表,但是这样未免太复杂
    • 所以我们采用带头节点的单链表在头部插入删除,把头部当中栈顶,这样精了很多。插入直接在头节点后插入。而删除也直接删除头节点后第一个元素即可。

    结构设计

    长话短说,短话不说。直接上代码就懂。
    链表的节点

    static class node<T>
    {
    	T data;
    	node next;
    	public node() {    
    	}
    	public node(T value)
    	{
    		this.data=value;
    	}
    }
    

    基本结构:

    public class lisStack <T>{
    	int length;
        node<T> head;//头节点
        public lisStack() {
    		head=new node<>();
    		length=0;
    	}
    	//其他方法
    }
    

    push插入

    与单链表头插入一致,如果不太了解请先看笔者队线性表介绍的。

    和数组形成的栈有个区别。就是理论上栈没有大小限制(不突破内存系统限制)。不需要考虑是否越界。

    • 节点team入栈
    • 空链表入栈head.next=team;
    • 非空入栈team.next=head.next;head.next=team;
      在这里插入图片描述

    pop弹出

    与单链表头删除一致,如果不太了解请先看笔者队线性表介绍的。

    和数组同样需要判断是否为空。

    • 节点team出栈
    • head指向team后驱节点。不需要考虑链表是否为1个节点。如果为1个节点,team.next=null.执行完毕head.next=null。变为空,满足条件。
      在这里插入图片描述

    其他操作

    • 其他例如peek操作时返回栈顶不弹出.所以只需判空满足题意时候return head.next.data即可。而length你可以遍历链表返回长度,也可以动态设置(本文采取)跟随栈长变化。其他操作直接看api。

    实现代码

    数组实现

    package 队栈;
    
    public class seqStack<T> {
    	
    	private T data[];
    	private int top;
    	public seqStack() {
    		data=(T[]) new Object[10];
    		top=-1;
    	}
    	public seqStack(int maxsize)
    	{
    		data=(T[]) new Object[maxsize];
    		top=-1;
    	}
    	boolean isEmpty()
    	{
    		return top==-1;
    	}
    	int length()
    	{
    		return top+1;
    	}
    	
    	boolean push(T value) throws Exception//压入栈
    	{
    		if(top+1>data.length-1)
    		{
    			throw new Exception("栈已满");
    		}
    		else {
    			data[++top]=value;
    			return true;
    		}
    	}
    	T peek() throws Exception//返回栈顶元素不移除
    	{
    		if(!isEmpty())
    		{
    			return data[top];
    		}
    		else {
    			throw new Exception("栈为空");
    		}
    	}
    	T pop() throws Exception
    	{
    		if(isEmpty())
    		{
    			throw new Exception("栈为空");
    		}
    		else {
    		   return data[top--];
    		}
    	}
    	public String toString()
    	{
    		if(top==-1)
    		{
    			return "";
    		}
    		else {
    			String va="";
    			for(int i=top;i>=0;i--)
    			{
    				va+=data[i]+"  ";
    			}
    			return va;
    		}
    	}
    }
    
    

    链表实现

    package 队栈;
    
    public class lisStack <T>{
    	static class node<T>
    	{
    		T data;
    		node next;
    		public node() {    
    		}
    		public node(T value)
    		{
    			this.data=value;
    		}
    	}
    	int length;
        node<T> head;//头节点
        public lisStack() {
    		head=new node<>();
    		length=0;
    	}
        boolean isEmpty()
    	{
    		return head.next==null;
    	}
    	int length()
    	{
    		return length;
    	}
        public void push(T value) {//近栈
           node<T> team=new node<T>(value);
           if(length==0)
           {
        	   head.next=team;
           }
           else {
    		team.next=head.next;
    		head.next=team;}
           length++;
        }
        public T peek() throws Exception {
            if(length==0) {throw new Exception("链表为空");}
            else {//删除
    			return (T) head.next.data;
    		}
      }
        public T pop() throws Exception {//出栈
              if(length==0) {throw new Exception("链表为空");}
              else {//删除
            	T value=(T) head.next.data;
    			head.next=head.next.next;//va.next
    			length--;
    			return value;
    			
    			
    		}
        }
        public String toString(){
        	if(length==0) {return "";}
        	else {
    			String va="";
    		    node team=head.next;
    		    while(team!=null)
    		    {
    		    	va+=team.data+" ";
    		    	team=team.next;
    		    }
    		    return va;
    		}
           
        }
    }
    

    测试

    在这里插入图片描述

    总结

    • 栈的逻辑比较简单。很容易理解,实现起来也相对容易。但是要注意数组情况的界限问题。
    • 后面将介绍队列,相比栈,队列内容更丰富一些。难度也稍大一些。
    • 如果有不好需要改进还请指出
    • 最后,喜欢的话可以关注公众号:bigsai 持续分享(回复 数据结构 获得精心准备资料一份!)

    在这里插入图片描述

    展开全文
  • 下面来介绍一下关于的一些基本操作结构定义: typedef struct { int data[MAXSIZE]; int top; /* 用于栈顶指针 */ }SqStack; 的初始化 Status InitStack(SqStack *S) { /* S.data=(SElemType *)malloc...

    什么是栈?
    栈 :是一种限定仅在表尾进行插入和删除操作的线性表。
    顾名思义,那栈的顺序存储其实也就是线性表顺序存储的简化,简称为顺序栈。
    下面来介绍一下关于栈的一些基本操作。

    栈的结构定义:

    typedef struct
    {
            int data[MAXSIZE];
            int top; /* 用于栈顶指针 */
    }SqStack;
    
    

    栈的初始化

    Status InitStack(SqStack *S)
    { 
            /* S.data=(SElemType *)malloc(MAXSIZE*sizeof(SElemType)); */
            S->top=-1;
            return OK;
    }
    

    判断栈是否为空

    Status StackEmpty(SqStack S)
    { 
            if (S.top==-1)
                    return TRUE;
            else
                    return FALSE;
    }
    

    入栈(插入一个元素e为新的栈顶元素)

    Status Push(SqStack *S,SElemType e)
    {
            if(S->top == MAXSIZE -1) /* 栈满 */
            {
                    return ERROR;
            }
            S->top++;				/* 栈顶指针增加一 */
            S->data[S->top]=e;  /* 将新插入元素赋值给栈顶空间 */
            return OK;
    }
    

    出栈(若栈不空,则删除S的栈顶元素,用e返回其值)

    Status Pop(SqStack *S,SElemType *e)
    { 
            if(S->top==-1)
                    return ERROR;
            *e=S->data[S->top];	/* 将要删除的栈顶元素赋值给e */
            S->top--;				/* 栈顶指针减一 */
            return OK;
    }
    

    当栈不空时,则用e返回S的栈顶元素

    Status GetTop(SqStack S,SElemType *e)
    {
            if (S.top==-1)
                    return ERROR;
            else
                    *e=S.data[S.top];
            return OK;
    }
    

    返回栈的长度

    int StackLength(SqStack S)
    { 
            return S.top+1;
    }
    

    从栈底到栈顶依次对栈中每个元素显示

    Status StackTraverse(SqStack S)
    {
            int i;
            i=0;
            while(i<=S.top)
            {
                    visit(S.data[i++]);
            }
            printf("\n");
            return OK;
    }
    

    整体的源代码如下

    #include "stdio.h"    
    
    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    #define MAXSIZE 20 /* 存储空间初始分配量 */
    
    typedef int Status; 
    typedef int SElemType; /* SElemType类型根据实际情况而定,这里假设为int */
    
    /* 顺序栈结构 */
    typedef struct
    {
            int data[MAXSIZE];
            int top; /* 用于栈顶指针 */
    }SqStack;
    
    Status visit(SElemType c)
    {
            printf("%d ",c);
            return OK;
    }
    
    /*  构造一个空栈S */
    Status InitStack(SqStack *S)
    { 
            /* S.data=(SElemType *)malloc(MAXSIZE*sizeof(SElemType)); */
            S->top=-1;
            return OK;
    }
    
    /* 把S置为空栈 */
    Status ClearStack(SqStack *S)
    { 
            S->top=-1;
            return OK;
    }
    
    /* 若栈S为空栈,则返回TRUE,否则返回FALSE */
    Status StackEmpty(SqStack S)
    { 
            if (S.top==-1)
                    return TRUE;
            else
                    return FALSE;
    }
    
    /* 返回S的元素个数,即栈的长度 */
    int StackLength(SqStack S)
    { 
            return S.top+1;
    }
    
    /* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
    Status GetTop(SqStack S,SElemType *e)
    {
            if (S.top==-1)
                    return ERROR;
            else
                    *e=S.data[S.top];
            return OK;
    }
    
    /* 插入元素e为新的栈顶元素 */
    Status Push(SqStack *S,SElemType e)
    {
            if(S->top == MAXSIZE -1) /* 栈满 */
            {
                    return ERROR;
            }
            S->top++;				/* 栈顶指针增加一 */
            S->data[S->top]=e;  /* 将新插入元素赋值给栈顶空间 */
            return OK;
    }
    
    /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
    Status Pop(SqStack *S,SElemType *e)
    { 
            if(S->top==-1)
                    return ERROR;
            *e=S->data[S->top];	/* 将要删除的栈顶元素赋值给e */
            S->top--;				/* 栈顶指针减一 */
            return OK;
    }
    
    /* 从栈底到栈顶依次对栈中每个元素显示 */
    Status StackTraverse(SqStack S)
    {
            int i;
            i=0;
            while(i<=S.top)
            {
                    visit(S.data[i++]);
            }
            printf("\n");
            return OK;
    }
    
    int main()
    {
            int j;
            SqStack s;
            int e;
            if(InitStack(&s)==OK)
                    for(j=1;j<=10;j++)
                            Push(&s,j);
            printf("栈中元素依次为:");
            StackTraverse(s);
            Pop(&s,&e);
            printf("弹出的栈顶元素 e=%d\n",e);
            printf("栈空否:%d(1:空 0:否)\n",StackEmpty(s));
            GetTop(s,&e);
            printf("栈顶元素 e=%d 栈的长度为%d\n",e,StackLength(s));
            ClearStack(&s);
            printf("清空栈后,栈空否:%d(1:空 0:否)\n",StackEmpty(s));
            
            return 0;
    }
    
    
    
    展开全文
  • 主要介绍了Java数据结构与算法是先进后出的数据的结构,本文通过文字说明实例代码相结合的形式给大家介绍的非常详细,需要的朋友跟着小编一起学习吧
  • 以下代码的存储结构定义和基本操作的实现。代码主要来自于严蔚敏老师的数据结构教材。代码在VC++ 6.0 和 Dev-C++下编译通过。 #include<stdio.h> #include<stdlib.h> #include<math.h>...

    以下代码为栈的存储结构定义和栈的基本操作的实现。代码主要来自于严蔚敏老师的数据结构教材。代码在VC++ 6.0 和 Dev-C++下编译通过。

    #include<stdio.h> 
    #include<stdlib.h> 
    #include<math.h> 
    
    #define TRUE 1
    #define FALSE 0
    #define OK 1
    #define ERROR 0
    
    typedef int Status; 
    typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
    typedef int SElemType;
    #define STACK_INIT_SIZE 20 /* 存储空间初始分配量*/
    #define STACKINCREMENT 10 /* 存储空间分配增量*/
    typedef struct SqStack
    {
    	SElemType *base; /* 在栈构造之前和销毁之后,base的值为NULL */
    	SElemType *top; /* 栈顶指针*/
    	int stacksize; /* 当前已分配的存储空间,以元素为单位*/
    }SqStack; /* 顺序栈*/
    
    Status InitStack(SqStack &S)
    { /* 构造一个空栈S */
    	S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
    	if(!S.base)
    		exit(OVERFLOW); /* 存储分配失败*/
    	S.top=S.base;
    	S.stacksize=STACK_INIT_SIZE;
    	return OK;
    }
    
    Status DestroyStack(SqStack &S)
    { /* 销毁栈S,S不再存在*/
    	free(S.base);
    	S.base=NULL;
    	S.top=NULL;
    	S.stacksize=0;
    	return OK;
    }
    
    Status ClearStack(SqStack &S)
    { /* 把S置为空栈*/
    	S.top=S.base;
    	return OK;
    }
    
    Status StackEmpty(SqStack S)
    { /* 若栈S为空栈,则返回TRUE,否则返回FALSE */
    	if(S.top==S.base)
    		return TRUE;
    	else
    		return FALSE;
    }
    
    int StackLength(SqStack S)
    { /* 返回S的元素个数,即栈的长度*/
    	return S.top-S.base;
    }
    
    Status GetTop(SqStack S,SElemType &e)
    { /* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
    	if(S.top>S.base)
    	{
    		e=*(S.top-1);
    		return OK;
    	}
    	else
    		return ERROR;
    }
    
    Status Push(SqStack &S,SElemType e)
    {
    	if(S.top - S.base >= S.stacksize) 
    	{
    		S.base = (SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
    		if(!S.base) 
    			exit (OVERFLOW); 
    		S.top = S.base + S.stacksize;
    		S.stacksize += STACKINCREMENT;
    	}
    	*(S.top)=e;
    	S.top++;
    	return OK;
    }
    
    Status Pop(SqStack &S,SElemType &e)
    { 
    //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR 
    	if(S.top==S.base)
    		return ERROR;
    	e=*(S.top-1);
    	--S.top;
    	return OK;
    }
    
    Status StackTraverse(SqStack S)
    { /* 从栈底到栈顶依次访问栈中每个元素*/
    	SElemType *p; 
    	p=S.base;
    	while(p<S.top)
    	{
    		printf("%d ",*p);
    		p++;
    	}
    	printf("\n");
    	return OK;
    }
    
    int main()
    {
    	int j;
    	SqStack s;
    	SElemType e;
    	if(InitStack(s)==OK)
    		for(j=1;j<=12;j++)
    			Push(s,j);
    	j=StackLength(s);
    	printf("栈中元素个数为:%d\n",j);
    	printf("栈中元素依次为:");
    	StackTraverse(s);
    	Pop(s,e);
    	printf("弹出的栈顶元素e=%d\n",e);
    	printf("栈空否:%d(1:空0:否)\n",StackEmpty(s));
    	GetTop(s,e);
    	printf("栈顶元素e=%d 栈的长度为%d\n",e,StackLength(s));
    	ClearStack(s);
    	j=StackEmpty(s);
    	printf("清空栈后,栈空否:%d(1:空0:否)\n",j);
    	DestroyStack(s);
    	printf("销毁栈后,s.top=%u s.base=%u s.stacksize=%d\n",s.top,s.base, s.stacksize);
    	return 0;
    }
    

     

    展开全文
  • 是一种受限的数据结构,具有先进后出,后进先出的特性,正因这种特性,用来做回文数完全符合要求,且思路清晰明了。 思路:用一个字符数组从键盘接收一个字符串,并把该字符数组中的元素...
  • 数据结构-顺序基本操作的实现(含全部代码

    万次阅读 多人点赞 2018-09-15 12:08:07
    主要操作函数如下: InitStack(SqStack &s) 参数:顺序s 功能:初始化 时间复杂度O(1) Push(SqStack &s,SElemType e) 参数:顺序s,元素e 功能:将e入栈 时间复杂度:O(1) Pop(SqStack &s,...
  • 数据结构 迷宫算法

    2018-12-20 12:49:57
    来求解迷宫的数据结构实验。求解迷宫的代码来自书上,迷宫只能在源代码上修改。
  • 数据结构与算法】常见数据结构基本操作

    万次阅读 多人点赞 2019-06-16 21:42:44
    数据结构基本操作+排序算法+查找算法目录1.数据结构与算法常见概念2.数据逻辑结构2.1线性结构2.2树形结构2.3图形结构2.4集合结构3.排序算法冒泡排序简单选择排序直接插入排序希尔排序堆排序归并排序快速排序4.查找...
  • 数据结构与算法设计》实验报告书之的存储结构定义及基本操作 实验项目 的存储结构定义及基本操作 实验目的 . 掌握的逻辑特征 . 掌握顺序存储结构的特点,熟练掌握顺序的基本运算 . 熟练掌握的链式存储...
  • 结构是一种非常常见的数据结构,并且在很多场景下也被用到。其实结构跟数组结构很像,只是在数组的基础...数据结构——一、什么是二、结构的方法三、用代码实现一个结构(1)创建一个构造函数(2)实现push
  • 主要介绍了用Java代码实现栈数据结构基本方法归纳,各种算法的实现也是ACM上经常出现的题目,是计算机学习的基本功,需要的朋友可以参考下
  • 【Java数据结构与算法及经典应用

    千次阅读 多人点赞 2020-04-18 20:07:30
    的应用场景介绍以及实现综合计算器
  • 数据结构与算法MOOC 第3周 栈与队列 参考代码
  • 数据结构与算法必知基础知识

    千次阅读 多人点赞 2021-01-06 22:58:12
    数据结构与算法是程序员内功体现的重要标准之一,且数据结构也应用在各个方面,业界更有程序=数据结构+算法这个等式存在。各个中间件开发者,架构师他们都在努力的优化中间件、项目结构以及算法提高运行效率和降低...
  • 迷宫问题——实现(C语言)(数据结构与算法

    千次阅读 多人点赞 2020-11-08 16:26:30
    本文用解决迷宫问题,采用C语言实现,包括问题介绍、算法简介、求解过程、代码实现、结果展示。并附有完整代码
  • “如何使用顺序表模拟以及实现对数据基本操作(出栈和入栈)” 给大家做详细介绍。 如果你仔细观察顺序表(底层实现是数组)和栈结构就会发现,它们存储数据的方式高度相似,只不过数据的存取过程有特殊...
  • 数组 数组实现队列 链表实现 链式存储队列 二分查找法 任意构造层次遍历输出 二叉排序树 先根建立二叉树及遍历 堆排 顺序两个迎面增长 树深度节点数 有序链表的合并 快速排序 头插法建立链表 循环链表实现队列
  • 目录 基础 c/c++ 代码优化及常见错误 ...除树和图外的数据结构可以使用STL: C++ STL的使用 数据结构 线性表 顺序表 循环左移(2010联考真题) 单链表 单链表相邻结点逆置(2019北邮考研真...
  • 系统堆栈的故事+数据结构中的堆和
  • 顺序栈基本操作代码实现

    千次阅读 2020-12-28 10:15:44
    顺序栈基本操作代码实现 /***顺序的实现***/ #include<iostream> using namespace std; #include<stdlib.h> #include<cstdlib> //顺序定义 #define OK 0 #define ERROR -1 #define OVERFLOW...
  • (中缀表达式转后缀表达式)原理及代码实现 1. 逆波兰表达式的介绍 2. 中缀转后缀的原因 3. 存储特点和原理 4. 实现中缀转后缀的思路 5. 代码实现 6. 注意事项 一,逆波兰表达式的介绍 前缀: 前缀表达式又称...
  • Java数据结构算法中文第二版源码

    热门讨论 2015-09-01 12:02:09
    数据结构算法能起到什么作用? 数据结构的概述 算法的概述 一些定义 面向对象编程 软件工程 对于C++程序员的Java Java数据结构的类库 小结 问题 第2章 数组 Array专题Applet Java中数组的基础知识 将程序划分成类...
  • java数据结构与算法(Stack)设计实现

    万次阅读 多人点赞 2016-11-28 12:27:43
    【版权申明】转载请注明出处(请尊重原创,博主...关联文章:java数据结构与算法之顺序表链表设计实现分析 java数据结构与算法之双链表设计实现 java数据结构与算法之改良顺序表双链表类似ArrayList和LinkedL
  • 有趣的数据结构算法8——的初始化、入栈出栈什么是栈栈的初始化入栈出栈实现代码GITHUB下载连接 新的结构又要出现了。我心里有点害怕,但是! 什么是 (stack)又名堆栈,它是一种运算受限的线性表。它的...
  • 数据结构与算法-栈与队列

    万次阅读 2018-04-02 17:58:31
    数据结构与算法-栈与队列 基本概念 简单表述就是仅在表尾进行插入和删除操作的线性表。 常见操作 入栈和出栈, 均在线性表的尾部进行。 基本原则就是, 先入后出。 队列 基本概念 和不同...
  • 由于文章有点多,并且发的文章也不是一个系列一个系列发的,不过我的文章大部分都是围绕着 数据结构 + 算法 + 计算机网络 + 操作系统 + Linux + 数据库 这几个方面发的,为了方便大家阅读,我整理了一波。...
  • 【源代码】C++实现严蔚敏数据结构所有算法(三)堆栈(VS2017)
  • Java数据结构与算法入门

    万次阅读 多人点赞 2018-04-29 11:53:50
    第一部分:Java数据结构要理解Java数据结构,必须能清楚何为数据结构数据结构:Data_Structure,它是储存数据的一种结构体,在此结构中储存一些数据,而这些数据之间有一定的关系。而各数据元素之间的相互关系,又...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 175,934
精华内容 70,373
关键字:

数据结构与算法栈的基本操作代码

数据结构 订阅