Java数据结构之 链式栈、循环队列

一. 链式栈

之前已经用数组实现了栈,用链栈也遵循先进后出的特点即可。

用链表实现入栈和出栈可以考虑头插法入栈和尾插法入栈。但不采用尾插法,因为这样每入栈或出栈一次,都要对栈进行一次遍历,增加了程序的复杂性。因此采用头插法,得到的链栈栈底元素为链表末尾元素,栈顶元素是头结点后的元素。

class LinkStack{
	Entry head;//头结点
	class Entry{
		int data;
		Entry next;
		public Entry(){
			this.data = -1;
			this.next = null;
		}
		public Entry(int val){
			this.data = val;
			this.next = null;
		}
	}
	public LinkStack(){//类的构造函数
		this.head = new Entry();
	}
}

1. 入栈

public void push(int val){
		Entry entry = new Entry(val);
		entry.next = this.head.next;
		this.head.next = entry;
	}

2. 出栈

public boolean pop(){
		if(head.next != null){//判断栈是否为空
			this.head.next = this.head.next.next;
			return true;
		}
		return false;
	}

3. 得到栈顶元素

public int getTop(){
		if(this.head.next != null){
			return head.next.data;
		}
		return -1;
	}

4.打印栈内元素

public void show(){
		Entry cur = head.next;
		while(cur != null){//遍历链表打印
			System.out.print(cur.data+" ");
			cur = cur.next;
		}
		System.out.println();
	}

测试一下


二. 循环队列

队列是一种先进先出的线性数据结构,即在队头进行删除,在队尾进行插入。队头用front表示,队尾用rear表示。

实现顺序队考虑用数组,但由于数组的长度有限,可能会出现如图假溢出的情况


循环队列


因此,我们构造的循环队列应该如下图


接下来看一下关于队列的基本操作

class QueueLink{
	int[] elem;//存放队列元素的数组
	int front;//队头
	int rear;//队尾
	
	int usedSize = 0;//循环队列内部的有效数据个数,即队列的长度
	int allSize = 10;//数组长度
	
	public QueueLink(){
		this(10);
	}
	public QueueLink(int size){
		this.elem = new int[size];
		this.front = 0;
		this.rear = 0;
	}
}

1. 判断队空

front = rear,队列为空

public boolean isEmpty(){
			return front == rear;//相等为true不相等为false
	}

2.判断队满

front = (rear + 1)%allsize

public boolean isFull(){
		if(this.front == (this.rear + 1) % allSize){//有一个闲置单元
			return true;
		}
		return false;
	}

3.入队

public void push(int val){
		if(isFull()){//队满不能入队
			return;
		}
		this.elem[this.rear] = val;
		this.rear = (this.rear + 1) % allSize;//不能rear++,rear一直在0~allsize-1的范围内
		this.usedSize++;//队列长度加一
	}

4. 出队

public void pop(){
		if(isEmpty()){//队空不出队
			return;
		}
		this.elem[front] = -1;//给出队的位置标志-1,表示这个元素已出队
		this.front = (this.front + 1)%allSize;//front后移一位
		this.usedSize--;//队列长度减一
	}

5.得到队头

public int getTop(){
		if(isEmpty()){//判断队空
			return -1;
		}
		return this.elem[front];//把front位置的元素return出去
	}

三. 用两个栈实现一个队列

public class TestDemo8 {
	Stack s1 = new Stack();
	Stack s2 = new Stack();
	public void pushQue(int val){//入队
		if(s1.isFull()){
			return;
		}
		s1.push(val);
	}
	public void popQue(){
		if(s1.isEmpty()){
			return;
		}
		while(s1.top > 1){//将s2除栈顶以外的元素放入s2
			s2.push(s1.getpop());
			s1.top--;
		}
		s1.top = 0;
		while(s2.top>0){//将s2的元素放回s1
			s1.push(s2.getpop());
			s2.top--;
		}
		
	}
	public  int getFront(){//得到队头
		if(s1.isEmpty()){
			return -1;
		}
		return s1.elem[0];
	}
	public void show(){
		for(int i = 0;i < s1.top;i++){
			System.out.print(s1.elem[i]+" ");
		}
		System.out.println();
	}
	public static void main(String[] args) {
		TestDemo8 t= new TestDemo8();
		t.pushQue(5);
		t.pushQue(6);
		t.pushQue(7);
		t.show();
		t.popQue();
		t.show();
	}
}





猜你喜欢

转载自blog.csdn.net/sinat_37003267/article/details/80240635