相信各位在大学数据结构课程便学习了栈、队列和链表的概念,在此我们从编码层面去理解其中的奥义。
栈
栈(Stack)是一种常见的数据结构,它是一种后入先出(Last In First Out, LIFO)的线性表。栈具有两个主要操作:入栈(push)和出栈(pop)。入栈是将元素放入栈顶,出栈是从栈顶删除元素。
栈只允许在线性表的某一端(栈顶)进行添加和删除,另一端不允许操作。
public class ArrayStack {
private int[] arr;
private int top;
public ArrayStack(int size){
arr = new int[size];
top=-1;
System.out.println("栈创建成功");
}
/**
* 入栈
* @param value
*/
public void push(int value){
if(top==arr.length-1){
throw new RuntimeException("栈已满,无法入栈");
}
arr[++top]=value;
}
/**
* 出栈
*/
public int pop(){
if(top==-1){
throw new RuntimeException("栈已空,无法出栈");
}
return arr[top--];
}
/**
* 查看栈顶元素
* @return
*/
public int peek(){
if(top==-1){
throw new RuntimeException("栈已空,无法查看栈顶元素");
}
return arr[top];
}
/**
* 判断栈是否为空
* @return
*/
public boolean isEmpty(){
return top==-1;
}
/**
* 判断栈是否已满
* @return
*/
public boolean isFull(){
return top==arr.length-1;
}
public String toString(){
return "ArrayStack{" +
"arr=" + java.util.Arrays.toString(arr) +
", top=" + top +
'}';
}
}
public static void testStack() {
ArrayStack arrayStack = new ArrayStack(10);
while (!arrayStack.isFull()) {
int random = new Random().nextInt(100);
System.out.println(String.format("入栈:%s", random));
arrayStack.push(random);
}
System.out.println(arrayStack);
while (!arrayStack.isEmpty()) {
System.out.println(String.format("查看栈顶元素:%s", arrayStack.peek()));
System.out.println(String.format("弹出栈顶元素:%s", arrayStack.pop()));
}
}
队列
队列(Queue)是一种受限制的线性数据结构,它遵循先进先出(First In First Out,FIFO)的原则。队列可以看作是一个具有两个端点的线性表,其中入队(enqueue)操作在队尾添加元素,出队(dequeue)操作则从队头移除元素。
队列只允许在某一端(队尾)进行添加,在另一端(队头)进行删除。
public class MyQueue {
/**
* 存放数据的数组
*/
public int[] array;
public int length;
public int head;
public int tail;
private int size;
public MyQueue(int length) {
this.array = new int[length];
this.length = length;
this.head = 0;
this.tail = -1;
this.size = 0;
}
/**
* 入队
* @param value
* @return
*/
public boolean enQueue(int value) {
if (size == length){
return false;
}
array[++tail]=value;
size++;
return true;
}
/**
* 出队,先进先出
* @return
*/
public int deQueue() {
if(size== 0){
return -1;
}
int value = array[head++];
size--;
return value;
}
/**
* 获取元素数量
* @return
*/
public int getQueueSize(){
return size;
}
/**
* 查看队列是否已满
* @return
*/
public boolean isFull(){
return size == length;
}
/**
* 查看队列是否空
* @return
*/
public boolean isEmpty() {
return size == 0;
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("Queue: ");
for (int i = head; i <= tail; i++) {
sb.append(array[i]);
if(i<tail){
sb.append(", ");
}
}
return sb.toString();
}
}
public static void TestQueue() {
MyQueue myQueue = new MyQueue(10);
while (!myQueue.isFull()) {
int random = new Random().nextInt(100);
System.out.println(String.format("入队:%s", random));
myQueue.enQueue(random);
}
System.out.println(myQueue);
while (!myQueue.isEmpty()) {
System.out.println(String.format("出队:%s", myQueue.deQueue()));
System.out.println(String.format("查看队列元素数:%s", myQueue.getQueueSize()));
}
}
链表
链表(Linked List)是一种线性数据结构,它由节点(Node)组成,每个节点包含数据元素和指向下一个节点的指针(或引用)。链表中最后一个节点的指针指向空(null),表示链表的末尾。
链表可以分为单向链表(Single Linked List)和双向链表(Double Linked List)两种形式。在单向链表中,每个节点只有一个指向下一个节点的指针;而在双向链表中,每个节点除了一个指向下一个节点的指针外,还有一个指向前一个节点的指针。
每个元素可以记住他的下一个节点,通常从根节点遍历。
public class LinkList {
Node head;
public LinkList() {
head = null;
}
//尾插法
public void add(int value) {
Node node = new Node(value);
if (head == null) {
head = node;
} else {
//遍历找到最后一个节点
Node temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = node;
}
}
//删除第一次出现关键字为value的节点
public void remove(int value) {
if (head == null) {
return;
}
//第一个节点是查找的值,那么第二个节点就为新头节点
if (head.value == value) {
head = head.next;
return;
}
//遍历查找
Node temp = head;
//持续遍历下个节点的value,直到找到匹配的
while (temp.next != null && temp.next.value != value) {
temp = temp.next;
}
//如果找到匹配的,删除,直接用下下节点引用替换下个节点的引用
if (temp.next != null && temp.next.value == value) {
temp.next = temp.next.next;
}
}
/**
* 打印链表
*/
public void printList() {
Node temp = head;
while (temp != null) {
System.out.print(temp.value+" ");
temp = temp.next;
}
System.out.println();
}
}
class Node {
int value;
Node next;
public Node(int value) {
this.value = value;
}
}