(一)队列和链表和栈(线性结构)

一. 队列

1. 队列的数组实现

因为要考虑复用问题,所以要实现循环队列,思路如下

(rear == front不能判断队列是空还是满,所以考虑牺牲一个空间)

(1). front:指向队列的第一个元素,初始值为0

(2).rear:指向队列最后一个元素的后一个位置,初始值为0

(3).当队列空时,rear == front

(4).当队列满时:(rear+1)%maxsize == front

(5).队列中元素个数:(rear+maxsize-front)%maxsize

public class ArrayQueue {
    private int maxSize;
    private int front;//指向第一个元素
    private int rear; //指向最后一个元素的下一个位置
    private int[] arr;

    public ArrayQueue(int maxSize){
        this.maxSize = maxSize;
        arr = new int[maxSize];
        front = 0;
        rear = 0;
    }

    //判断队列是否为空
    public boolean isEmpty(){
        return front == rear;
    }
    //判断队列是否满
    public boolean isFull(){
        return (rear+1)%maxSize == front;
    }
    //队列中元素的个数
    public int getNum(){
        return (rear+maxSize-front)%maxSize;
    }
    //取出队列的首元素
    public int pop(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        int result =  arr[front];
        front = (front+1)%maxSize;
        return result;
    }
    //添加元素到队列中
    public void add(int value){
        if (isFull()){
            throw new RuntimeException("队列已满");
        }
        arr[rear] = value;
        rear = (rear+1)%maxSize;
    }
    //查看队列的第一个元素
    public int peek(){
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return arr[front];
    }
    //查看队列中的所有元素
    public void getAll(){
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        for (int i = front; i < front+getNum(); i++){
            System.out.print(arr[i]+ " ");
        }
    }

}

二. 单链表

1. 单链表的实现

public class SingleLinkedList {
    private Node head = new Node(0,"");
    //添加节点
    public void add(Node node){
        Node temp = head;
        while (temp.next != null){
            temp = temp.next;
        }
        temp.next = node;
    }
    //遍历链表
    public void list(){
        if (head.next == null){
            System.out.println("链表为空");
            return;
        }
        Node temp = head;
        while (true){
            System.out.println(temp);
            if (temp.next == null){
                return;
            }
            temp = temp.next;
        }
    }
     //按顺序添加元素
    public void addByOrder(Node node){
        Node temp = head;
        while (true){
            if (temp.next == null){
                break;
            }
            if (node.no == temp.no){
                throw new RuntimeException("该编号已经存在");
            }
            if (temp.next.no > node.no){
                break;
            }

            temp = temp.next;
        }
        node.next = temp.next;
        temp.next =node;
    }
    //删除节点
    public void remove(int no){
        Node temp = head;
        while (true){
            if (temp.next == null){
                throw new RuntimeException("未找到该元素");
            }
            if (temp.next.no == no){
                break;
            }
            temp = temp.next;
        }
        temp.next = temp.next.next;
    }



}
class Node{
    public int no;
    public String name;
    public Node next;
    public Node(int no,String name){
        this.no = no;
        this.name = name;
    }

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

2. 单链表的反转

(1).递归实现

public Node reverse(Node head) {
    if (head == null || head.next == null)
        return head;
    Node temp = head.next;
    Node newHead = reverse(head.next);
    temp.next = head;
    head.next = null;
    return newHead;
}

(2).遍历实现

blic static Node reverseList(Node node) {
  Node pre = null;
  Node next = null;
  while (node != null) {
      next = node.next;
      node.next = pre;
      pre = node;
      node = next;
  }
  return pre;
}

3. 双向链表的实现

public class DoubleLinkedList {
    DoubleNode head = new DoubleNode(0);
    //遍历,修改同单向链表
    //添加双向链表
    public void add(DoubleNode node){
        DoubleNode temp = head;
        while (temp.next != null){
            temp = temp.next;
        }
        temp.next = node;
        node.pre = temp;
    }
    //删除节点
    public void remove(int data){
        DoubleNode temp = head;
        while (true){
            if (temp == null){
                throw new RuntimeException("未找到该元素");
            }
            if (temp.data == data){
                break;
            }
            temp = temp.next;
        }
        if (temp.next != null){
            temp.next.pre = temp.pre;
        }
        temp.pre.next = temp.next;

    }
    //遍历链表
    public void list(){
        if (head.next == null){
            System.out.println("链表为空");
            return;
        }
        DoubleNode temp = head;
        while (true){
            System.out.println(temp.data);
            if (temp.next == null){
                return;
            }
            temp = temp.next;
        }
    }
}

4. 约瑟夫问题(循环链表)

/*
* 约瑟夫问题
*/
public class CircleLinkedList {
    public static void main(String[] args) {
        CircleLinkedList circleLinkedList = new CircleLinkedList();
        circleLinkedList.addNode(5);
        circleLinkedList.countBoy(1,2,5);
    }
    private DoubleNode first = new DoubleNode(-1);
    //环形链表创建
    private void addNode(int nums){
        if (nums < 1){
            System.out.println("编号不正确");
            return;
        }
        DoubleNode cur = null;//辅助指针
        for (int i=1; i <= nums; i++){
            DoubleNode boy = new DoubleNode(i);
            if (i == 1){
                first = boy;
                //构成环状
                first.next = first;
                cur = first;
            }else {
                cur.next = boy;
                boy.next = first;
                cur = boy;
            }
        }
    }
    //打印环形链表
    public void show(){
        if (first == null){
            System.out.println("链表为空");
        }
        DoubleNode cur = first;
        while (true){
            System.out.println(cur.data+" ");
            if (cur.next == first)break;
            cur = cur.next;
        }
    }
    //根据用户输入计算出小孩出圈顺序
    //从第startNo个小孩开始数数
    //countNum表示数几下
    //nums表示有几个小孩在圈中
    public void countBoy(int startNum, int countNum, int nums){
        if (first == null || startNum < 1 ||startNum > nums){
            System.out.println("参数输入有误");
        }
        //创建一个辅助指针,指向first的前一个节点
        DoubleNode helper = first;
        while (true){
            if (helper.next == first)break;
            helper = helper.next;
        }
        //报数开始前,先让first和helper移动到指定的位置
        for (int i = 0; i < startNum-1; i++){
            first = first.next;
            helper = helper.next;
        }
        while (true){
            if (helper == first)break;
            //让helper和first同时移动count-1.此时first指向的节点就是要出圈的小孩
            for(int j = 0; j < countNum-1; j++){
                first = first.next;
                helper = helper.next;
            }
            System.out.print(first.data+" ");
            first = first.next;
            helper.next = first;
        }
        System.out.print(first.data+" ");
    }
}

三. 栈

1. 栈的数组实现

public class ArrayStack {

    private int top = -1;
    private int[] array;
    private int maxSize;

    public ArrayStack(int maxSize){
        this.maxSize = maxSize;
        array = new int[maxSize];
    }

    //判满
    public boolean isFull(){
        if (top == maxSize-1){
            return true;
        }
        return false;
    }

    //判空
    public boolean isEmpty(){
        if (top == -1){
            return true;
        }
        return false;
    }

    //入栈
    public void push(int a){
        if (isFull()){
            System.out.println("栈满");
            return;
        }
        array[++top] = a;
    }

    //出栈
    public int pop(){
        if (isEmpty()){
            throw new RuntimeException("栈空");
        }
        int number = array[top];
        top--;
        return number;
    }

    //遍历栈
    public void list(){
        if (isEmpty())return;
        while (top != -1){
            System.out.print(array[top]+" ");
            top--;
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值