java数据结构

目录

1稀疏数组

1.1使用场景

1.2 代码实现

2环形队列数组实现

3 链表

3.1 带头节点的单链表实现

环形链表(约瑟夫问题)


1稀疏数组

1.1使用场景

当一个数组中大部分的元素为0,或为同一个值的数组时,可以使用稀疏数组来保存该数组。

1.2 代码实现



import java.util.Arrays;

/**
 * @ClassName: SparseArray
 * @Author: haojie.sun
 * @Description: 稀疏数组与普通二维数组的转化(五子棋)
 * @Date: 2021/2/18 9:58
 * @Version: 1.0
 */
public class SparseArray {
    public static void main(String[] args) {
        // 新建一个二维数组,模拟一个五子棋的棋盘
        int[][] arr = new int[15][15];
        System.out.println("初始数组");
        showArr(arr);
        // 假设棋盘上共有2个棋子
        arr[2][2] =1;
        arr[3][3]=2;
        System.out.println("棋子数组");

        showArr(arr);
        // 保存为稀疏数组
       // 判断稀疏数组的行
        int sum = 0;
        for (int i = 0; i < 15; i++) {
            for (int j = 0; j < 15; j++) {
                if (arr[i][j] !=0) {
                    sum++;
                }
            }
        }
        System.out.println("非0数据" + sum);
        int[][] sparseArray = new int [sum+1][3];

        sparseArray[0][0] = 15;
        sparseArray[0][1]= 15;
        sparseArray[0][2]= sum;
        int k =0;
        for (int i = 0; i < 15; i++) {
            for (int j = 0; j < 15; j++) {
                if (arr[i][j] !=0) {
                    k++;
                    sparseArray[k][0]=i;
                    sparseArray[k][1]=j;
                    sparseArray[k][2]=arr[i][j];
                }
            }
        }
        System.out.println("稀疏数组");
        showArr(sparseArray);

    }
    private static void showArr(int[][] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.println(Arrays.toString(arr[i]));
        }
    }

}

2环形队列数组实现

 

 

  1. 当队列不为空时,front指向队列的第一个元素,rear指向队列最后一个元素的下一个位置。
  2. 当队列为空时,front=rear
  3. 队列满时:(rear+1)%maxsiz=front,少用一个存储空间,也就是数组的最后一个存数空间不用

循环队列的相关条件和公式:

1.队空条件:rear==front

2.队满条件:(rear+1) %QueueSIze==front,其中QueueSize为循环队列的最大长度

3.计算队列长度:(rear-front+QueueSize)%QueueSize

4.入队:(rear+1)%QueueSize

5.出队:(front+1)%QueueSize

 



import java.util.Arrays;
import java.util.Scanner;

/**
 * @ClassName: CircleArrayQueue
 * @Author: haojie.sun
 * @Description: 环形数组模拟队列
 *
 * @Date: 2021/2/18 9:59
 * @Version: 1.0
 */
public class CircleArrayQueueDemo {
    public static void main(String[] args) {
        CircleArrayQueue queue = new CircleArrayQueue(4);
        boolean flag = true;
        while (flag) {
            System.out.println("请输入 e: 退出, a 新增,g:获取, h:第一个元素, s: 查看队列, q: 查看数组");
            Scanner scanner = new Scanner(System.in);
            char c = ' ';
            c = scanner.next().charAt(0);
            switch (c){
                case 'e':
                    flag = false;
                    break;
                case 'a':
                    System.out.println("请输入数字");
                    int val = scanner.nextInt();
                    try{
                        queue.add(val);

                    }catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'g':
                    System.out.println(queue.get());
                    break;
                case 'h':
                    try{
                        System.out.println(queue.head());
                    }catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 's':
                    queue.showQueue();
                    break;
                case 'q':
                    System.out.println(queue);
                    break;
                default:
                    break;
            }

        }
        System.out.println("退出");
    }
}
class CircleArrayQueue{
    int front;
    int end;
    int[] arr;
    int maxSize;
    public CircleArrayQueue(int size){
        maxSize =size;
        arr = new int[maxSize];
    }
    public boolean isEmpty(){
        return front == end;
    }
    public boolean isFull() {
        return (end + 1) % maxSize == front;
    }

    //新增
    public void add (int n) {
        if (isFull()) {
           throw new RuntimeException("队列已满,不能增加");
        }
        arr[end] = n;
        end = (end+1)%maxSize;
    }
    //取出
    public int get () {
        if (isEmpty()) {
            throw new RuntimeException("队列为空,不能取出");
        }
        int value = arr[front];
        front = (front+1)%maxSize;
        return value;
    }
    // 查看队列
    public void showQueue() {
        for (int i = front; i < front + size(); i++) {
            System.out.printf("queue[%d]=%d\n", (i % maxSize), arr[i % maxSize]);
        }
    }
    // 队列中的有效元素
    public int size() {
        return (end - front +maxSize) % maxSize;
    }

    public int head() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空");
        }
        return arr[front];
    }

    @Override
    public String toString() {
        return "CircleArrayQueue{" +
                "front=" + front +
                ", end=" + end +
                ", arr=" + Arrays.toString(arr) +
                ", maxSize=" + maxSize +
                '}';
    }
}

3 链表

3.1 带头节点的单链表实现

存储的节点内容



import java.util.Objects;

/**
 * @ClassName: Node
 * @Author: haojie.sun
 * @Description:
 * @Date: 2021/2/18 14:51
 * @Version: 1.0
 */
public class Node {
    private  int no;
    private String name;
    private String nickName;
    private Node next;
    public Node(int no, String name, String nickName) {
        this.name = name;
        this.no = no;
        this.nickName = nickName;
    }
    public boolean hashNext() {
        return Objects.nonNull(this.getNext());
    }
    public void setNext(Node next) {
        this.next = next;
    }

    public Node getNext() {
        return next;
    }

    public int getNo() {
        return no;
    }

    @Override
    public String toString() {
        return "Node{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Node node = (Node) o;
        return no == node.no &&
                Objects.equals(name, node.name) &&
                Objects.equals(nickName, node.nickName) ;
    }

    @Override
    public int hashCode() {
        return Objects.hash(no, name, nickName, next);
    }
}

实现并测试单向链表

package com.shj.home.datastruct;

import java.util.Objects;

/**
 * @ClassName: SingleLinkedList
 * @Author: haojie.sun
 * @Description:
 * @Date: 2021/2/18 14:50
 * @Version: 1.0
 */
public class SingleLinkedListDemo {
    public static void main(String[] args) {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        Node n1 = new Node(1,"n1", "nc1");
        Node n2 = new Node(2,"n2", "nc2");
        Node n3 = new Node(3,"n3", "nc3");
        Node n4 = new Node(4,"n4", "nc4");
        Node n5 = new Node(5,"n5", "nc5");
        addList(singleLinkedList,n1,n2,n3,n4,n5);
        singleLinkedList.list();
        singleLinkedList.remove(n1);
        singleLinkedList.remove(n1);
        System.out.println(singleLinkedList.getSize());
        singleLinkedList.list();
        Node n11 = new Node(11,"n11", "nc1");
        Node n12 = new Node(12,"n12", "nc2");
        Node n13 = new Node(13,"n13", "nc3");
        Node n14 = new Node(14,"n14", "nc4");
        Node n15 = new Node(15,"n15", "nc5");
//        singleLinkedList = null;
        SingleLinkedList singleLinkedList1 = new SingleLinkedList();
        addSortedList(singleLinkedList1,n11,n12,n13,n14,n15);
        System.out.println(singleLinkedList1.getSize());
        singleLinkedList1.list();
        singleLinkedList1.remove(n11);
        singleLinkedList1.remove(n12);
        singleLinkedList1.list();

    }

    private static void addList(SingleLinkedList singleLinkedList,Node n1, Node n2, Node n3, Node n4, Node n5) {
        singleLinkedList.addList(n1);
        // 如果加入重复的节点,则会无限加
//        singleLinkedList.addList(n1);
        singleLinkedList.addList(n2);
        singleLinkedList.addList(n4);
        singleLinkedList.addList(n5);
        singleLinkedList.addList(n3);
    }
    private static void addSortedList(SingleLinkedList singleLinkedList,Node n1, Node n2, Node n3, Node n4, Node n5) {
        singleLinkedList.addSorted(n5);
        singleLinkedList.addSorted(n4);
        singleLinkedList.addSorted(n3);
        singleLinkedList.addSorted(n5);
        singleLinkedList.addSorted(n3);
        singleLinkedList.addSorted(n1);
    }
}

class  SingleLinkedList {
    private Node head;
    private  int size;
    public SingleLinkedList() {
        // 初始化头节点
        head = new Node(-1,"","");
    }


    // add
    public void addList(Node node){
        Node temp = head;
        while(true) {
            if(temp.getNext() == null) {
                temp.setNext(node);
                size ++;
                break;
            }
            else {
                temp = temp.getNext();
            }
        }
    }
    public int getSize(){
        return size;
    }
    public void remove(Node node){
        Node temp = head;
        while(true) {
            if (Objects.isNull(temp)) {
                System.out.println("已到末尾,没有对应的元素");
                break;
            }
            System.out.println("temp-<"+temp);
            if(Objects.nonNull(temp.getNext()) &&temp.getNext().equals(node)) {
                temp.setNext(node.getNext());
                System.out.println("已删除元素");
                size--;
                break;
            }
            else {
                temp = temp.getNext();
            }
        }
    }
    public  void addSorted(Node node) {
        Node temp = head;
        while(true) {
            if (temp.hashNext()) {
                // 判断下一个元素
                if(temp.getNext().getNo() == node.getNo()) {
                    System.out.printf("已存在编号为%d的元素\n", node.getNo());
                    break;
                }
                if(temp.getNext().getNo() > node.getNo()) {
                    //下一个元素比要插入的大
                    Node next =  temp.getNext();
                    temp.setNext(node);
                    temp.getNext().setNext(next);
                    System.out.println("插入成功");
                    size++;
                    break;
                }
                if(temp.getNext().getNo() < node.getNo()) {
                    //下一个元素比要插入的小
                    temp = temp.getNext();
                }
            }
            else {
                temp.setNext(node);
                break;
            }

        }
    }
    // 遍历
    public void list() {
        Node temp = head;
        while(true) {
            if (temp.hashNext()) {
                System.out.println(temp);
                temp = temp.getNext();
            }
            else{
                System.out.println(temp);
                break;
            }
        }
    }
}

环形链表(约瑟夫问题)

有m个人围成一圈,从n开始,每数到k,出圈,

public class JosepfuLinkedListDemo {
    public static void main(String[] args) {
        JosepfuLinkedList list = new JosepfuLinkedList();
        list.add(5);
//        list.list();
        list.show(1, 2, 5);
    }

}
// 环形链表
class JosepfuLinkedList{
    public Boy head;

    public Boy getHead() {
        return head;
    }

    private boolean isEmpty() {
        return head.next ==null;
    }
    public void add(int nums) {
        if (nums <1) {
            System.out.println("长度输入不合法");
            return;
        }
        Boy temp = null;
        for (int i = 1; i <= nums ; i++) {
            Boy curr = new Boy(i);
            if (i == 1) {
                // 第一个也要成环
               head = curr;
               head.next = head;
               temp = head;
            }
            else {
                temp.next = curr;
                curr.next = head;
                temp = curr;
            }
        }
    }
    public void list() {
        if (isEmpty()) {
            System.out.println("没有数据");
            return;
        }
        Boy temp = head;
        while (true) {
            if (temp.next == head) {
                System.out.println(temp.no);
                break;
            }
            System.out.println(temp.no);
            temp = temp.next;
        }
    }

    public void show(int n, int k , int num){
        if (n <1 || k<1 || num<k)  {
            System.out.println("输入不合法");
            return;
        }
        if (head == null) {
            System.out.println("空的");
            return;
        }
        // 找到尾部的节点
        Boy end = head;
        while(true) {
            if(end.next == head) {
                break;
            }
            end = end.next;
        }
        // 从第n个人开始
        for (int i = 0; i < n -1 ; i++) {
            head = head.next;
            end = end.next;
        }
        while(true) {
            if(end == head) {
                System.out.println("last " + head.no);
                break;
            }
            // 每次数k出圈
            for (int i = 0; i < k-1 ; i++) {
                head =head.next;
                end = end.next;
            }
            System.out.println("out " + head.no);
            head = head.next;
            end.next = head;
        }
    }
}
class Boy{
    public int no;
    public Boy next;
    public Boy(int no){
        this.no =no;
    }

    @Override
    public String toString() {
        return "Boy{" +
                "no=" + no +
                '}';
    }
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hero_孙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值