赞
踩
栈是一种后进先出或先进后出的线性表,其插入和删除操作只允许在表的尾端进行。
栈中允许进行插入和删除操作的一端称为栈顶(top),另一端称为栈底(bottom)。
通常,人们将栈的插入操作称为入栈(push),而将删除操作称为出栈(pop)。
1. 顺序栈(使用数组实现)
顺序栈的存储结构示意图
- //顺序栈
- public class SqStack {
-
- private int[] stackElem; //对象数组
- private int top; //在非空栈中,top始终指向栈顶元素的下一个存储位置;当栈为空时,top=0
-
- public static void main(String[] args) throws Exception {
- //测试
- SqStack st = new SqStack(5); //构建一个长度为5的顺序栈
- System.out.println(st.isEmpty()); //判空
- System.out.println(st.length()); //返回栈的长度
- st.push(1); //入栈
- st.push(2);
- st.push(3);
- st.display(); //打印
- System.out.println();
- st.pop(); //出栈
- st.display();
- System.out.println(); //打印
- System.out.println(st.isEmpty());
- System.out.println(st.length());
- }
-
- public SqStack(int maxSize) {
- top = 0; //初始化
- stackElem = new int[maxSize]; //为栈分配maxSize个存储单元
- }
-
- //1. 置栈空
- public void clear() {
- top = 0;
- }
-
- //2. 判断栈是否为空
- public boolean isEmpty() {
- return top == 0;
- }
-
- //3. 求栈中数据元素个数
- public int length() {
- return top;
- }
-
- //4. 取栈顶元素
- public int peek() {
- if(!isEmpty())
- return stackElem[top-1];
- else
- return -1;
- }
-
- //5. 入栈
- public void push(int x) throws Exception{
- if(top == stackElem.length) //判断是否栈满
- throw new Exception("栈已满"); //抛出异常
- else
- stackElem[top++] = x; //先将新的数据元素x压入栈顶,再top增加1
- }
-
- //6. 出栈
- public int pop(){
- if(isEmpty()) //判断栈是否为空
- return -1;
- else
- return stackElem[--top];
- }
-
- //7. 输出栈中所有元素
- public void display() {
- for(int i=top-1;i>=0;i--) {
- System.out.print(stackElem[i] + " "); //输出
- }
- }
-
- }
【注:
top的定义方式有两种——
一种是将其设置为指向栈顶元素存储位置的下一个存储单元的位置,则空栈时,top=0;
另一种是将top设置为指向栈顶元素的存储位置,则空栈时,top=-1。
再次采用前一种方式来表示栈顶。】
2. 链栈(使用不带头结点的单链表实现)
链栈的存储结构示意图
- //使用泛型构造结点类
- public class Node<T> {
- public T data; //存放结点值
- public Node<T> next; //后继结点的引用
- //无参时的构造函数
- public Node(){
- this(null,null);
- }
- //带一个参数时的构造函数
- public Node(T data){
- this(data,null);
- }
- //带两个参数时的构造函数
- public Node(T data,Node<T> next)
- {
- this.data=data;
- this.next=next;
- }
- }
- //链栈
- public class LinkStack<T> {
-
- private Node<T> top; //栈顶元素的应用
-
- public static void main(String[] args) throws Exception {
- //测试
- LinkStack<Integer> ls = new LinkStack<Integer>();
- System.out.println(ls.isEmpty()); //判空
- System.out.println(ls.length()); //返回栈的长度
- ls.push(1); //入栈
- ls.push(2);
- ls.push(3);
- ls.display(); //打印
- System.out.println();
- ls.pop(); //出栈
- ls.display();
- System.out.println(); //打印
- System.out.println(ls.isEmpty());
- System.out.println(ls.length());
-
- }
-
- //1. 置栈空
- public void clear() {
- top = null;
- }
-
- //2. 判断栈是否为空
- public boolean isEmpty() {
- return top == null;
- }
-
- //3. 求栈中数据元素个数
- public int length() {
- Node<T> p = top; //初始化,p指向栈顶元素
- int length = 0; //length为长度计数器
- while(p != null) { //从栈顶元素开始向后查找,直到p指向空
- p = p.next; //p指针后移
- ++length; //长度加1
- }
- return length; //返回长度
- }
-
- //4. 取栈顶元素
- public T peek() {
- if(!isEmpty()) //栈非空
- return top.data; //返回栈顶元素
- else
- return null;
- }
-
- //5. 入栈
- public void push(T x) throws Exception{
- Node<T> p = new Node<T>(x); //构造一个新结点
- p.next = top;
- top = p; //新结点成为当前的栈顶元素
- }
-
- //6. 出栈
- public T pop(){
- if(isEmpty())
- return null;
- else {
- Node<T> p = top; //p指向被删结点(即栈顶元素)
- top = top.next; //修改链指针,使栈顶结点从链栈中移去
- return p.data; //返回被删结点数据域的值
- }
- }
-
- //7. 输出栈中所有元素
- public void display() {
- Node<T> p = top; //初始化,p指向栈顶元素
- while(p != null) { //输出所有非空结点的数据元素值
- System.out.print(p.data.toString() + " ");
- p = p.next; //p指针后移
- }
- }
-
- }
队列是一种先进先出或后进后出的线性表,只允许在表尾插入数据,在表头删除数据。
允许进行插入的一端称为是队尾(rear),允许进行删除的一端称为是队首(front)。
队列的插入操作通常称为入队操作(push),而删除操作通常称为出队操作(pop)。
1. 顺序队列(使用数组实现)
顺序队列的存储结构示意图
- //循环顺序队列
- public class SqQueue {
-
- private int[] queueElem; //队列存储空间
- private int front; //队首的引用,若队列不空,指向队首元素
- private int rear; //队尾的引用,若队列不空,指向对队尾元素的下一个存储位置
-
- public static void main(String[] args) throws Exception{
- //测试
- SqQueue sq = new SqQueue(5);
- sq.display();
- sq.offer(1); //入队
- sq.offer(2);
- sq.offer(3);
- sq.display(); //打印
- System.out.println();
- System.out.println(sq.poll()); //出队
- sq.display(); //打印
- System.out.println();
- System.out.println(sq.isEmpty()); //判空
- System.out.println(sq.length()); //长度
- }
-
- //构造函数
- public SqQueue(int maxSize) {
- front = rear = 0; //队首、队尾初始化为0
- queueElem = new int[maxSize]; //为队列分配maxSize个存储单元
- }
-
- //1. 队列置空
- public void clear() {
- front = rear = 0;
- }
-
- //2. 判断队列是否为空
- public boolean isEmpty() {
- return front == rear;
- }
-
- //3. 求队列的长度
- public int length() {
- return (rear-front + queueElem.length) % queueElem.length;
- }
-
- //4. 读取队首元素
- public int peek() {
- if(front == rear) //队列为空
- return -1;
- else
- return queueElem[front]; //返回队首元素
- }
-
- //5. 入队
- public void offer(int x) throws Exception{
- if((rear+1) % queueElem.length == front) //队列满
- throw new Exception("队列已满"); //抛出异常
- else {
- queueElem[rear] = x; //x存入rear所指的数组存储位置中,使其成为新的队尾元素
- rear = (rear+1) % queueElem.length; //修改队尾指针
- }
- }
-
- //6. 出队
- public int poll() {
- if(front == rear) //队列空
- return -1;
- else {
- int t = queueElem[front];
- front = (front+1) % queueElem.length; //修改队首指针
- return t; //返回队首元素
- }
- }
-
- //7. 输出队列中的所有数据元素(从队首到队尾)
- public void display() {
- if(!isEmpty()) {
- for(int i=front;i!=rear;i=(i+1)%queueElem.length)
- System.out.print(queueElem[i] + " ");
- }else {
- System.out.println("队列为空");
- }
- }
-
- }
【注:
顺序队列会因数组下标越界而引起“假溢出”,故在此将顺序队列所使用的存储空间看成是一个逻辑上首尾相连的循环队列。】
2. 链队列(使用不带头结点的单链表实现)
链队列的存储结构示意图
- //链队列
- public class LinkQueue<T> {
-
- private Node<T> front; //队首指针
- private Node<T> rear; //队尾指针
-
- public static void main(String[] args) throws Exception{
- //测试
- LinkQueue<Integer> lq = new LinkQueue<Integer>();
- lq.display();
- lq.offer(1); //入队
- lq.offer(2);
- lq.offer(3);
- lq.display(); //打印
- System.out.println();
- System.out.println(lq.poll()); //出队
- lq.display(); //打印
- System.out.println();
- System.out.println(lq.isEmpty()); //判空
- System.out.println(lq.length()); //长度
- }
-
- //构造函数
- public LinkQueue() {
- front = rear = null;
- }
-
- //1. 队列置空
- public void clear() {
- front = rear = null;
- }
-
- //2. 判断队列是否为空
- public boolean isEmpty() {
- return front == null;
- }
-
- //3. 求队列的长度
- public int length() {
- Node<T> p = front; //p指针指向队首元素
- int length = 0; //计数器
- while(p != null) { //只要p不为空
- p = p.next; //指针后移
- ++length; //计数器+1
- }
- return length; //返回长度
- }
-
- //4. 读取队首元素
- public T peek() {
- if(front != null) //队列不为空
- return front.data; //返回队首结点的数据域值
- else
- return null;
- }
-
- //5. 入队
- public void offer(T x) throws Exception{
- Node<T> p = new Node<T>(x); //初始化新结点
- if(front != null) { //队列非空
- rear.next = p;
- rear = p; //修改队尾的位置
- }else
- front = rear = p;
- }
-
- //6. 出队
- public T poll() {
- if(front != null) { //队列非空
- Node<T> p = front; //p指向队首结点
- front = front.next; //队首结点出列
- if(p == rear) //若被删除的结点是队尾结点时
- rear = null;
- return p.data; //返回队首结点的数据域值
- }
- else
- return null;
- }
-
- //7. 输出队列中的所有数据元素(从队首到队尾)
- public void display() {
- if(!isEmpty()) {
- Node<T> p = front;
- while(p != null) {
- System.out.print(p.data.toString() + " ");
- p = p.next;
- }
- }else {
- System.out.println("队列为空");
- }
- }
-
- }
1. 栈和队列的相同点
2. 栈对队列的不同点
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。