手撕代码总结(纯Java版)------数据结构

链表

头插法
    public void addFirst(int data) {
        // 1. 拿到一个实体
        Node node = new Node(data);

        // 2. 插入
        // 如果是第一次插入,直接到头节点
        if (this.head == null) {
            this.head = node;
        } else { //不是第一次插入
            node.next = this.head; // 插入的节点指向头节点
            this.head = node;      // 更新头节点
        }
    }
尾插法
    public void addLast(int data) {
        // 1. 拿到一个实体
        Node node = new Node(data);
        Node cur = this.head;

        // 2. 插入
        // 如果是第一次插入,直接到头节点
        if (this.head == null) {
            this.head = node;
        } else {
            // 找尾巴
            while (cur.next != null) {
                cur = cur.next;
            }
            // 退出上面的循环,cur所执行的位置就是尾节点
            cur.next = node;
        }
    }
任意位置插入
    public boolean addIndex(int index, int data) {
        Node node = new Node(data);
        Node cur = searchIndex(index);

        // 如果链表为空,直接插入到头节点
        if (cur == null) {
            node.next = this.head;
            this.head = node;
        } else { // 链表不为空,插入到 cur 的位置处
            node.next = cur.next;  // 将node链接到cur的下一个节点
            cur.next = node;       // 再将cur链接到node
        }

        return true;
    }
查找是否包含
    public boolean contains(int key) {
        Node cur = this.head;
        while (cur != null) {
            if (cur.data == key) {
                return true;
            }
            cur = cur.next;
        }

        return false;
    }
删除元素(首次出现)
    public int remove(int key) {
        int oldData = 0;
        Node pre = searchPre(key);

        // 1. 若没有找到
        if (pre == null) {
            // return -1;
            throw new UnsupportedOperationException("没有key的前驱");
        }

        // 2. 找到了,并且在第一个节点
        if (pre == this.head && pre.data == key){
            oldData = this.head.data;
            this.head = this.head.next;
            return oldData;
        }

        // 3. 找到了,并且不在第一个节点
        Node delNode = pre.next; // 确定要删除的节点的位置
        pre.next = delNode.next; // 让要删除的节点的前驱指向要删除的节点的后一个节点,进而删除该节点

        return 0;
    }

先序遍历(DLR)
public void preOrder(TreeNode treeNode) {
		if(treeNode!= null) {
			System.out.print(treeNode.getValue()+" ");
			preOrder(treeNode.getLeftTreeNode());
			preOrder(treeNode.getRightTreeNode());
		}
	}

非递归

public void preOrder1(TreeNode root) {
    if(root==null) return;
    // 栈,保存访问过的节点
    LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
    TreeNode node = root;
    while(!stack.isEmpty() || node!=null) {
        // 一直往左下遍历
        while(node!=null) {
            stack.push(node);
            nodesVal.add(node.val);
            node = node.left;
        }
        // 无左子树的时候,去判断右子树
        node = stack.pop();
        node = node.right;
    }
}
中序遍历(LDR)
public void inOrder(TreeNode treeNode) {
		if(treeNode!=null) {
			midOrder(treeNode.getLeftTreeNode());
			System.out.print(treeNode.getValue() +" ");
			midOrder(treeNode.getRightTreeNode());
		}
	}

非递归

public void inOrder() {
		Node current = root;
		//把LinkedList作为栈使用
		LinkedList<Node> s = new LinkedList<Node>();
		while (current != null || !s.isEmpty()) {
			while (current != null) {
				s.addFirst(current);
				current = current.left;
			}
			if (!s.isEmpty()) {
				current = s.removeFirst();
				System.out.print(current.data + " -> ");
				current = current.right;
			}
		}
	}


后序遍历(LRD)
public void afterOrder(TreeNode treeNode) {
		if(treeNode!=null) {
			afterOrder(treeNode.getLeftTreeNode());
			afterOrder(treeNode.getRightTreeNode());
			System.out.print(treeNode.getValue() + " ");
		}
	}

非递归

    public void postTraversal1(TreeNode root) {
        Deque<TreeNode> stack = new LinkedList<>();
        // 当前正在遍历的结点
        TreeNode cur = root;
        // 刚被弹出栈的结点.
        TreeNode pre = null;
        while (!stack.isEmpty() || cur != null) {
            // 当 cur 不为空时, 将左边的结点一直压栈
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            // 当 cur 为空时, 查看栈顶元素
            TreeNode top = stack.peek();
            if (top.right == null) {
                // 无右孩子
                System.out.println(top.val);
                pre = stack.pop();
            } else if (top .right == pre) {
                // 有右孩子并且右孩子已经被遍历过
                System.out.println(top.val);
                pre = stack.pop();
            } else {
                // 右孩子没有被遍历过.
                cur = top.right;
            }
        }
    }
层次遍历
public void levelTraverse(TreeNode root) {  
        if (root == null) {  
            return;  
        }  
        LinkedList<TreeNode> queue = new LinkedList<>();  
        queue.offer(root);  
        while (!queue.isEmpty()) {  
            TreeNode node = queue.poll();  
            System.out.print(node.val+"  ");  
            if (node.left != null) {  
                queue.offer(node.left);  
            }  
            if (node.right != null) {  
                queue.offer(node.right);  
            }  
        }  
    }  
深度遍历
public void depthOrderTraverse(TreeNode root) {  
        if (root == null) {  
            return;  
        }  
        LinkedList<TreeNode> stack = new LinkedList<>();  
        stack.push(root);  
        while (!stack.isEmpty()) {  
            TreeNode node = stack.pop();  
            System.out.print(node.val+"  ");  
            if (node.right != null) {  
                stack.push(node.right);  
            }  
            if (node.left != null) {  
                stack.push(node.left);  
            }  
        }  
    }  
查找
public boolean Search(Integer val) {
		if(root == null) {
			return false;
		}
		TreeNode treeNode = root;
		while(treeNode!=null) {
			if(treeNode.getValue()==val)
				return true;
			else if(treeNode.getValue()>val)
				treeNode = treeNode.getLeftTreeNode();
			else
				treeNode = treeNode.getRightTreeNode();
		}
		return false;
	}

public class AMWGraph {
    private ArrayList vertexList;//存储点的链表
    private int[][] edges;//邻接矩阵,用来存储边
    private int numOfEdges;//边的数目
    boolean[] isVisited = new boolean[8];
 
    public AMWGraph(int n) {
        //初始化矩阵,一维数组,和边的数目
        edges=new int[n][n];
        vertexList=new ArrayList(n);
        numOfEdges=0;
    }
 
    //得到结点的个数
    public int getNumOfVertex() {
        return vertexList.size();
    }
 
    //得到边的数目
    public int getNumOfEdges() {
        return numOfEdges;
    }
 
    //返回结点i的数据
    public Object getValueByIndex(int i) {
        return vertexList.get(i);
    }
 
    //返回v1,v2的权值
    public int getWeight(int v1,int v2) {
        return edges[v1][v2];
    }
 
    //插入结点
    public void insertVertex(Object vertex) {
        vertexList.add(vertexList.size(),vertex);
    }
 
    //插入结点
    public void insertEdge(int v1,int v2,int weight) {
        edges[v1][v2]=weight;
        numOfEdges++;
    }
 
    //删除结点
    public void deleteEdge(int v1,int v2) {
        edges[v1][v2]=0;
        numOfEdges--;
    }
 
    //得到第一个邻接结点的下标
    public int getFirstNeighbor(int index) {
        for(int j=0;j<vertexList.size();j++) {
            if (edges[index][j]>0) {
                return j;
            }
        }
        return -1;
    }
 
    //根据前一个邻接结点的下标来取得下一个邻接结点
    public int getNextNeighbor(int v1,int v2) {
        for (int j=v2+1;j<vertexList.size();j++) {
            if (edges[v1][j]>0) {
                return j;
            }
        }
        return -1;
    }
DFS
    //私有函数,深度优先遍历
    private void depthFirstSearch(boolean[] isVisited,int  i) {
        //首先访问该结点,在控制台打印出来
        System.out.print(getValueByIndex(i)+"  ");
        //置该结点为已访问
        isVisited[i]=true;
         
        int w=getFirstNeighbor(i);
        while (w!=-1) {
            if (!isVisited[w]) {
                depthFirstSearch(isVisited,w);
            }
            w=getNextNeighbor(i, w);
        }
    }
     
    //对外公开函数,深度优先遍历,与其同名私有函数属于方法重载
    public void depthFirstSearch() {
        for(int i=0;i<getNumOfVertex();i++) {
            //因为对于非连通图来说,并不是通过一个结点就一定可以遍历所有结点的。
			if (!isVisited[i]) {
                depthFirstSearch(isVisited,i);
            }
        }
    }
BFS
    //私有函数,广度优先遍历
    private void broadFirstSearch(boolean[] isVisited,int i) {
        int u,w;
        Queue<Integer> queue=new LinkedList<>();  //队列
         
        //访问结点i
        System.out.print(getValueByIndex(i)+"  ");
        isVisited[i]=true;
        //结点入队列
        queue.add(i);
        while (!queue.isEmpty()) {
            u=((Integer)queue.poll()).intValue();
            w=getFirstNeighbor(u);
            while(w!=-1) {
                if(!isVisited[w]) {
                    //访问该结点
                    System.out.print(getValueByIndex(w)+"  ");
                    //标记已被访问
                    isVisited[w]=true;
                    //入队列
                    queue.add(w);
                }
                //寻找下一个邻接结点
                w=getNextNeighbor(u, w);
            }
        }
    }
    
    //对外公开函数,广度优先遍历
    public void broadFirstSearch() {
        for(int i=0;i<getNumOfVertex();i++) {
            if(!isVisited[i]) {
                broadFirstSearch(isVisited, i);
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值