public class LinkStack<E> {
private class Node<E>{
E e;
Node<E> next;
public Node(){}
public Node(E e, Node next){
this.e = e;
this.next = next;
}
}
private Node<E> top; //栈顶元素
private int size; //当前栈大小
public LinkStack(){
top = null;
}
//当前栈大小
public int length(){
return size;
}
//判空
public boolean empty(){
return size==0;
}
//入栈:让top指向新创建的元素,新元素的next引用指向原来的栈顶元素
public boolean push(E e){
top = new Node(e,top);
size ++;
return true;
}
//查看栈顶元素但不删除
public Node<E> peek(){
if(empty()){
throw new RuntimeException("空栈异常!");
}else{
return top;
}
}
//出栈
public Node<E> pop(){
if(empty()){
throw new RuntimeException("空栈异常!");
}else{
Node<E> value = top; //得到栈顶元素
top = top.next; //让top引用指向原栈顶元素的下一个元素
value.next = null; //释放原栈顶元素的next引用
size --;
return value;
}
}
}
编程模拟实现一个浏览器的前进、后退功能
队列
用数组实现一个顺序队列
public class SeqQueue<E> {
private Object[] data = null;
private int maxSize; //队列容量
private int front; //队列头,允许删除
private int rear; //队列尾,允许插入
//构造函数
public SeqQueue() {
this(10);
}
public SeqQueue(int initialSize) {
if (initialSize >= 0) {
this.maxSize = initialSize;
data = new Object[initialSize];
front = rear = 0;
} else {
throw new RuntimeException("初始化大小不能小于0:" + initialSize);
}
}
//判空
public boolean empty() {
return rear == front ? true : false;
}
//插入
public boolean add(E e) {
if (rear == maxSize) {
throw new RuntimeException("队列已满,无法插入新的元素!");
} else {
data[rear++] = e;
return true;
}
}
//返回队首元素,但不删除
public E peek() {
if (empty()) {
throw new RuntimeException("空队列异常!");
} else {
return (E) data[front];
}
}
//出队
public E poll() {
if (empty()) {
throw new RuntimeException("空队列异常!");
} else {
E value = (E) data[front]; //保留队列的front端的元素的值
data[front++] = null; //释放队列的front端的元素
return value;
}
}
//队列长度
public int length() {
return rear - front;
}
}
用链表实现一个链式队列
public class LinkQueue<E> {
private class Node<E> {
E e;
Node<E> next;
public Node() {
}
public Node(E e, Node next) {
this.e = e;
this.next = next;
}
}
private Node front;// 队列头,允许删除
private Node rear;// 队列尾,允许插入
private int size; //队列当前长度
public LinkQueue() {
front = null;
rear = null;
}
//判空
public boolean empty(){
return size==0;
}
//插入
public boolean add(E e){
if(empty()){ //如果队列为空
front = new Node(e,null);//只有一个节点,front、rear都指向该节点
rear = front;
}else{
Node<E> newNode = new Node<E>(e, null);
rear.next = newNode; //让尾节点的next指向新增的节点
rear = newNode; //以新节点作为新的尾节点
}
size ++;
return true;
}
//返回队首元素,但不删除
public Node<E> peek(){
if(empty()){
throw new RuntimeException("空队列异常!");
}else{
return front;
}
}
//出队
public Node<E> poll(){
if(empty()){
throw new RuntimeException("空队列异常!");
}else{
Node<E> value = front; //得到队列头元素
front = front.next;//让front引用指向原队列头元素的下一个元素
value.next = null; //释放原队列头元素的next引用
size --;
return value;
}
}
//队列长度
public int length(){
return size;
}
}
实现一个循环队列
public class LoopQueue<E> {
public Object[] data = null;
private int maxSize; // 队列容量
private int rear;// 队列尾,允许插入
private int front;// 队列头,允许删除
private int size=0; //队列当前长度
public LoopQueue() {
this(10);
}
public LoopQueue(int initialSize) {
if (initialSize >= 0) {
this.maxSize = initialSize;
data = new Object[initialSize];
front = rear = 0;
} else {
throw new RuntimeException("初始化大小不能小于0:" + initialSize);
}
}
// 判空
public boolean empty() {
return size == 0;
}
// 插入
public boolean add(E e) {
if (size == maxSize) {
throw new RuntimeException("队列已满,无法插入新的元素!");
} else {
data[rear] = e;
rear = (rear + 1)%maxSize;
size ++;
return true;
}
}
// 返回队首元素,但不删除
public E peek() {
if (empty()) {
throw new RuntimeException("空队列异常!");
} else {
return (E) data[front];
}
}
// 出队
public E poll() {
if (empty()) {
throw new RuntimeException("空队列异常!");
} else {
E value = (E) data[front]; // 保留队列的front端的元素的值
data[front] = null; // 释放队列的front端的元素
front = (front+1)%maxSize; //队首指针加1
size--;
return value;
}
}
// 队列长度
public int length() {
return size;
}
//清空循环队列
public void clear(){
Arrays.fill(data, null);
size = 0;
front = 0;
rear = 0;
}
}
链表
实现单链表、循环链表、双向链表、支持增删操作
普通链表node
public class ListNode {
public int val;
public ListNode next;
public ListNode(int x) {
this.val = x;
}
}
实现单链表反转
public class Solution {
public static ListNode reverseList(ListNode head) {
ListNode prev = null;
// 当前结点的下一个节点将成为当前节点的上一个节点 重复操作
// input 1 2 3 4 5 null
// output 5 4 3 2 1 null
ListNode tmp = null;
while (head != null) {
// 暂存下一个节点 用于向后遍历
tmp = head.next;
// 获得当前节点的前驱 实现反转
head.next = prev;
// prev保存当前节点 当前结点为下一个节点的 前驱
prev = head;
// 遍历下一个 2
head = tmp;
}
// 最后一轮prev指向原链表的最后一个节点 即反转链表的头
return prev;
}
public static ListNode reverseList(ListNode head, int m, int n) {
if (m == n || head == null) {
return head;
}
ListNode tmp = null;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode p=dummy;
for (int i = 0; i < m - 1; i++) {
p = p.next;
}
// p.next此时为开始反转的位置
ListNode tail = p.next;
for (int i = m; i < n; i++) {
tmp = p.next;
p.next = tail.next;
tail.next = tail.next.next;
p.next.next = tmp;
}
return dummy.next;
}