栈(Stack)
分为顺序结构和链表结构 特点:先进后出,后进先出
顺序结构
存储线性表的数据元素的方式 = 一段地址连续的存储单元
在类的内部使用数组来存储元素,数组的大小会根据需要动态的变化,因为有一个resize()方法,使用N来表示栈顶的上面一个位置,入栈时,先将元素放入data[N],N再进行加一的操作;反之,出栈时,先将N减一,取出元素,再置此时data[N]的值为nul
public class ArrayStack<Item> implements Iterable<Item> {
private Item[] data = (Item[]) new Object[1]; // 栈里的数据
private int N = 0; // 栈的元素个数
public boolean isEmpty(){
return N==0;
}
public int length(){
return N;
}
public void resize(int len){
Item[] temp = (Item[]) new Object[len];
for (int i=0; i<N; i++){
temp[i] = data[i];
}
data = temp;
}
public void push(Item item){
if (N == data.length){
this.resize(2* data.length);
}
data[N++] = item;
}
public Item pop(){
Item item = data[--N];
data[N] = null; // 避免对象游离
if (N>0 && N==data.length/4){
this.resize(data.length/2);
}
return item;
}
@Override
public Iterator<Item> iterator() {
return new ReverseArrayIterator();
}
// 内部类
public class ReverseArrayIterator implements Iterator<Item>{
private int i = N;
public boolean hasNext(){
return i>0;
}
public Item next(){
return data[--i];
}
public void remove(){
}
}
public static void main(String[] args) {
ArrayStack<Integer> testStack = new ArrayStack<>();
testStack.push(1);
testStack.push(2);
testStack.push(3);
testStack.push(4);
for (Integer i:testStack){
System.out.println(i);
}
testStack.pop();
for (Integer i:testStack){
System.out.println(i);
}
}
}
链式结构
结构特点 存储线性表的数据元素的方式 = 一段地址不连续、任意的存储单元 设定一个top指针表示栈顶,所以显然当top为null时,表示栈空。入栈:新建一个oldTop变量指向此时的top指向,再让top指向新插入的元素结点,再设其next指针指向oldTop;出栈:只需在取出元素之后让栈顶指针指向下一个元素即可
public class Stack<Item> implements Iterable<Item> {
private Node top;
private int N;
private class Node{
Item item;
Node next;
public Node(Item item, Node next) {
this.item = item;
this.next = next;
}
}
public boolean isEmpty(){
return top==null;
}
public int length(){
return N;
}
public void push(Item item){
Node oldTop = top;
top = new Node(item,oldTop);
N = N + 1;
}
public Item pop(){
Item item = top.item;
top = top.next;
return item;
}
@Override
public Iterator<Item> iterator() {
return new StackIterator();
}
private class StackIterator implements Iterator<Item>{
private Node current = top;
@Override
public boolean hasNext() {
return current != null;
}
@Override
public Item next() {
Item item = current.item;
current = current.next;
return item;
}
}
}
队列
特点:先进先出
顺序队列
特点:使用一组地址连续的内存单元依次保存数据,也可以定义一个特定大小的结构数组作为队列
public class CirQueue {
private Object[] objs;
private int front = 0;// 头指针
private int rear = 0;// 尾指针
private int size;// 空间大小
private int length = 0;
// 初始化
public CirQueue(int size) {
this.size = size;
objs = new Object[size];
}
// 计算长度(即队列元素个数)
public int getLength() {
return length;
}
// 判空
public boolean isEmpty() {
if (front == rear) {
return true;
}
return false;
}
// 判满
public boolean isFull() {
if ((rear + 1) % size == front) {
return true;
}
return false;
}
// 入队
public boolean enQueue(Object n) {
if (isFull()) {
return false;
}
rear = (rear + 1) % size;// 体现循环
objs[rear] = n;
length++;
return true;
}
// 出队
public Object deQueue() {
Object n = null;
if (!isEmpty()) {
front = (front + 1) % size;// 体现循环
n = objs[front];
objs[front] = null;
length--;
}
return n;
}
// 输出
public void show() {
for (Object obj : objs) {
if (obj == null) {
System.out.print("空 ");
} else {
System.out.print(obj.toString() + " ");
}
}
System.out.println("");
}
}
链式队列
public class QueueLink implements Queue {
// 定义一个节点内部类
class Node {
private Object data;
private Node next;
public Node(Object obj) {
this.data = obj;
}
public Node() {
}
}
// 定义链式队列的一些属性
private Node head; // 头指针(引用)
private Node rear; // 尾指针(引用)
private int length; // 队列的长度,开始为1
private Node temp; // 临时指针(引用)
// 初始化队列,空头指针
public QueueLink() {
head = new Node();
rear = head;
length = 1;
}
// 初始化队列,有数据头指针
public QueueLink(Object obj) {
head = new Node(obj);
rear = head;
length = 1;
}
public boolean clear() {
// TODO Auto-generated method stub
if(this.length==1){
return true;
}else if(length==2){
head.next=null;
//没有引用的节点java会自动回收内存
}else {
while(head.next.next!=null){
head.next=head.next.next;
}
head.next=null;
return true;
}
return false;
}
// 判空
public boolean isEmpty() {
// TODO Auto-generated method stub
if (this.length() == 1) {
return true;
} else {
return false;
}
}
// 获得队列的长度
public int length() {
// TODO Auto-generated method stub
return this.length;
}
// 添加一个节点
public void offer(Object x) {
this.temp = new Node(x);
// 队列使用尾插法
rear.next = temp;
rear = temp;
this.length++;
// TODO Auto-generated method stub
}
// 查看第一个节点
public Node peek() {
// TODO Auto-generated method stub
if (length == 1) {
temp=null;
} else {
temp= head.next;
}
return temp;
}
//删除第一个节点
public Node poll() {
// TODO Auto-generated method stub
if(length==1){
//无法删除
temp=null;
}else
if(length==2){
this.temp= head.next;
//置空下一个节点就可以了
head.next=null;
length--;
}else{
this.temp= head.next;
this.head.next=this.head.next.next;
length--;
}
return temp;
}
//test
public static void main(String[] args) {
QueueLink linkQueue = new QueueLink();
System.out.println("队列是否为空:"+linkQueue.isEmpty());
System.out.println("连续入队-------------------------------");
for(int i=0;i<5;i++){
linkQueue.offer((char)(97+i));
}
System.out.println("队列长度为:"+linkQueue.length());
System.out.println("队首元素为:"+linkQueue.peek().data);
//出队
System.out.println("连续出队-------------------------------");
for(int i=0;i<4;i++){
Object data=linkQueue.poll();
}
System.out.println("队列长度为:"+linkQueue.length());
}
}