1.队列是一种先入先出的数据结构,在入队添加数据时,入队只能在队列尾部添加,在出队时,只能移除最先进入的元素,即队列头部。维护两个指针,队头和队尾初始都是-1。
下面为队列的定义和队列设计的基本操作 code
。
class ArrayQueue{
private int maxSize;//最大容量
private int front;//队列头
private int rear;//队列尾
private int[] arr;//用来实现队列的数组
//构造器
public ArrayQueue(int arrMaxSize){
maxSize = arrMaxSize;
front = -1;
rear = -1;
arr = new int[maxSize];
}
//判断队列是否满
public boolean isFull(){
return rear = maxSize - 1;
}
//判断队列是否为空
public boolean isEmpty(){
return front == rear;//头尾在一起,说明为空
}
//入队操作
Public void addQueue(int val){
if(isFull){
return;
}
rear++;
arr[rear] = val;//后移之后在这个位置添加元素
}
//出队操作
public int getQueue(){
if(isEmpty){
return;
}
front++;
return arr[front];
}
//遍历显示队列数据
public void showQueue(){
if(isEmpty){
System.out.println("队列为空");
return;
}
for(int i = 0;i<arr.length;i++){
System.out.println("arr[%d]=%d\n",i,arr[i]);
}
}
// 显示队列头数据,不是取出
public int headQueue(){
if(isEmpty){
System.out.println("队列为空,没有数据");
}
return arr[front + 1];
}
}
2.栈是一种先入后出的数据结构,在栈顶添加元素,删除元素即出栈也是在栈顶,不像队列,这里我们只维护一个栈顶为-1。每添加一个元素,栈顶++,出栈一个元素,top–,遍历元素从栈顶开始。
class ArrayStack{
private int maxSize;
private int top;
private int[] stack;
public ArrayStack(int maxSize){
this.maxSize = maxSize;
top = -1;
stack = new int[MaxSize];
}
//栈满
public void isFull(){
return top = maxSize -1;
}
//z栈空
public void isEmpty(){
return top == -1;
}
//入栈
public void push(int val){
if(isFull){
System.out.println("栈满")
}
top++;
stack[top] = val;
}
//出栈
public int pop(){
if(isEmpty){
System.out.println("栈空");
}
int value = stack[top];
top--;
}
//遍历栈,要从栈顶开始显示
public void showStack(){
if(isEmpty){
System.out.println("栈空");
}
for(int i = top; i>=0; i--){
System.out.println("stack[%d]=%d\n",i,stack[i]);
}
}
}
3.二叉树的组成实现以及三种遍历方式
//定义二叉树
public class TreeNode{
int val;
TreeNode left;
TreeNode right;
TreeNode(){}
TreeNode(int val){this.val = val;}
TreeNode(int val,TreeNode left,TreeNode right){
this.val = val;
this.left = left;
this.right = right;
}
}
前序遍历,按照根节点——左子树——右子树的方式添加,在遍历的过程中,我们维护一个栈结构,通过栈结构使得元素出栈入栈达到不同顺序遍历的目的。
public List<Integer> preoderTraversal(TreeNode root){
List<Integer> res = new ArrayList<>();
LinkedList<Integer> stack = new LinkedList<>();
if(root==null){
return res;
}
TreeNode node = root;
while(node!=null||!stack.isEmpty){
while(node!=null){
res.add(node.val);
stack.push(node);
node = node.left;
}
node = stack.pop();
node = node.right;
}
return res;
}
中序遍历
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
LinkedList<TreeNode> stack= new LinkedList<>();
while(root == null){
return res;
}
TreeNode node = root;
while(node!=null||!stack.isEmpty()){
while(node!=null){
stack.push(node);
node = node.left;
}
node = stack.pop();
res.add(node.val);
node = node.right;
}
return res;
}
后序遍历
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
LinkedList<TreeNode> stack = new LinkedList<>();
if(root==null){
return res;
}
TreeNode node = root;
TreeNode pre = null;
while(node!=null||!stack.isEmpty()){
while(node!=null){
stack.push(node);
node = node.left;
}
node = stack.pop();
if(node.right==null|node.right==pre){
res.add(node.val);
pre = node;
node = null;
}else{
stack.push(node);
node = node.right;
}
}
return res;
}
}
4.HashSet实现
HashSet使用哈希函数来组织数据,支持快速插入和搜索,根据哈希函数计算获得相同的值,则放在同一个桶里,因此HashSet使用集合来创建,用于存储非重复的值,关键在于如何设计哈希函数。
class MyHashSet {
private int size = 1000; //hashset的长度
private LinkedList<Integer>[] map;//一个外容器hashset
/** Initialize your data structure here. */
public MyHashSet() {
map = new LinkedList[size];
for(int i = 0; i < size;i++){
map[i] = new LinkedList<>(); //在外容器的每一个元素添加一个桶,这个桶也是用链表实现
}
}
private int hash(int key){ //哈希函数
return key%size;
}
public void add(int key) { //添加,用哈希函数找到要放置的桶,把这个桶赋给一个链表引用。如果这个桶不包含这个key则添加
int index = hash(key);
LinkedList<Integer> list = map[index];
if(list.contains(key)==false){
list.add(key);
}
}
public void remove(int key) { //删除,同样用哈希函数找到要放置的桶,把这个桶赋给一个链表引用,遍历这个桶的元素,如果有就删掉
int index1 = hash(key);
LinkedList<Integer> list1 = map[index1];
for(Integer data : list1){
if(data == key){
list1.remove(data);
return;
}
}
}
/** Returns true if this set contains the specified element */
public boolean contains(int key) {
int idx = hash(key);
LinkedList<Integer> list3 = map[idx];
return list3.contains(key);
}
}
5.HashMap实现
class MyHashMap {
public class Node{ //现在而言,每个桶里维护的是一个Node节点
public int key;
public int val;
public Node(){
}
public Node(int key,int val){
this.key = key;
this.val = val;
}
}
private int size = 100;
private LinkedList<Node>[] map;
/** Initialize your data structure here. */
public MyHashMap() { //一样的,外部容器的每个元素还是维护一个链表
map = new LinkedList[size];
for(int i = 0; i<size;i++){
map[i] = new LinkedList<>();
}
}
public int hash(int key){
return key % size;
}
/** value will always be non-negative. */
public void put(int key, int value) {
int index = hash(key);
LinkedList<Node> map1 = map[index];
for(Node node : map1){ //遍历map1
if(node.key == key){ //这里就是相当于如果这个节点已经有了key,那么就更新key
node.val = value;
return;
}
}
Node cur = new Node(key,value); 遍历完了之后,没执行if里的代码,那么久新建一个节点,将这个节点挂在后面
map1.add(cur);
}
/** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
public int get(int key) {
int index = hash(key);
LinkedList<Node> map2 = map[index];
for(Node node : map2){ Node指的是map2里的元素类型,node是形参 map2是集合引用,增强for循环嘛
if(node.key == key){
return node.val;
}
}
return -1;
}
/** Removes the mapping of the specified value key if this map contains a mapping for the key */
public void remove(int key) {
int index = hash(key);
LinkedList<Node> map3 = map[index];
for(Node node : map3){
if(node.key == key){
map3.remove(node);
return;
}
}
}
}