环形队列和单链表

环形队列相关操作

        注:需要判断条件,需要front指向队尾 rear指向队头

 public boolean isFull() {
        return (rear + 1) % maxsize == front;
    }

    public boolean isEmpty() {
        return rear == front;
    }

1.添加数据进队列

public void addQueue(int num) {
        if (isFull()) {
            System.out.println("队列已满...");
            return;
        }
        arr[rear] = num;
        rear = (rear + 1) % maxsize;
    }

2.出队列

public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空...");
        }
        int val = arr[front];
        front = (front + 1) % maxsize;
        return val;
    }

3.获取有效数据个数

public int size() {
        return (rear + maxsize - front) % maxsize;
    }

4.显示队列头信息

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

5.显示所有数据

public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列为空...");
            return;
        }
        for (int i = front; i < front + size(); i++) {
            System.out.printf("arr[%d]=%d\n", i % maxsize, arr[i % maxsize]);
        }
    }

单链表

        注:每个节点不一定连续存储

                每个节点都包含data域和next域指向下一个节点

                分情况带头节点或不带头节点

1.首先初始化一个头节点

 //初始化头节点    不存储数据
    private HeroNode head = new HeroNode(1, "", "");

2.添加节点到链表

 public void add(HeroNode heroNode) {
        //头节点不能动
        HeroNode temp = head;
        while (true) {
            if (temp.next == null) {
                break;
            }
            temp = temp.next;
        }
        temp.next = heroNode;
    }    

3.遍历链表

public void list() {
        //头节点不能动
        HeroNode temp = head.next;

        if (head.next == null) {
            System.out.println("该链表为空");
            return;
        }
        while (true) {
            if (temp == null) {
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }

 4.按照节点编号添加进链表

public void addByOrder(HeroNode heroNode) {
        boolean flag = false;

        HeroNode temp = head;

        while (true) {
            if (temp.next == null) break;

            if (temp.next.no > heroNode.no) break;

            else if (temp.next.no == heroNode.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            System.out.printf("%d 编号已经存在\n", heroNode.no);
        } else {
            heroNode.next = temp.next;    //已经到链表末尾
            temp.next = heroNode;
        }
    }

5.修改节点信息

public void update(HeroNode heroNode) {

        if (head.next == null) {
            return;
        }

        HeroNode temp = head.next;
        boolean flag = false;

        while (true) {

            if (temp == null) break;

            if (temp.no == heroNode.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if (flag) {
            temp.nickName = heroNode.nickName;
            temp.name = heroNode.name;
        } else System.out.printf("未找到 %d \n", heroNode.no);
    }

6.删除节点

public void delete(int no) {
        HeroNode temp = head;
        boolean flag = false;

        while (true) {
            if (temp.next == null) break;

            if (temp.next.no == no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if (flag) {
            temp.next = temp.next.next;
        } else System.out.printf("此编号 %d 不存在", no);
        
    }

7.获取链表长度

public int length() {
        HeroNode temp = head;
        if (temp.next == null) {
            return 0;
        }
        int len = 0;
        while (temp.next != null) {
            len++;
            temp = temp.next;
        }
        return len;
    }

8.获取链表倒数第k个值

public HeroNode findLastNode(HeroNode head, int index) {
        if (head == null)
            return null;

        int size = 4;

        if (index <= 0 || index > size)
            return null;

        HeroNode cur = head.next;
        for (int i = 0; i < size - index; i++) {
            cur = cur.next;
        }
        return cur;
    }

        此处应该用方法获取size但由于太懒...

9.链表反转

public void reserveList() {
        if (head.next == null || head.next.next == null) return;

        //创建一个新链表
        HeroNode reverseHead = new HeroNode(0, "", "");
        //遍历之前的链表
        HeroNode cur = head.next;
        HeroNode next ;
        while (cur != null) {
            next = cur.next;
            cur.next = reverseHead.next;//将下一个节点指向新链表最前端
            reverseHead.next = cur;//将cur定为新头
            cur = next;//后移
        }
        head.next = reverseHead.next; //将原链表头指向新链表
    }

此处有必要说明一下

        cur.next = reverseHead.next;

        是将原来链表cur的下一个节点,指向新链表头节点的下一个节点。

        然后再用

        reverseHead.next = cur;

        将cur节点连接到新链表

10.链表逆序打印

public void reservePrint(){
        if (head.next==null) return;

        Stack<HeroNode> stack = new Stack<>();

        HeroNode temp=head.next;
        while (temp!=null){
            stack.push(temp);
            temp=temp.next;
        }
        while (stack.size()>0) {
            System.out.println(stack.pop());
        }
    }

11.按照编号合并两个链表

public static HeroNode mergeOrderList(HeroNode head1, HeroNode head2) {
        HeroNode NewHead = new HeroNode(0, "", "");

        HeroNode tail = NewHead;
        NewHead.next=tail;

        HeroNode temp1 = head1.next;
        HeroNode temp2 = head2.next;

        while (temp1 != null && temp2 != null) {
            Integer flag=compareNode(temp1,temp2);
            if (flag.equals(1)){    //节点1大于节点2

                HeroNode next=temp2.next;
                temp2.next=null;
                tail.next=temp2;
                tail=temp2;
                temp2=next;

            }else if (flag.equals(0)) {//节点1小于节点2

                HeroNode next=temp1.next;
                temp1.next=null;
                tail.next=temp1;
                tail=temp1;
                temp1=next;

            }
            else {  //相等
                HeroNode next1=temp1.next;
                HeroNode next2=temp2.next;

                temp1.next=null;
                tail.next=temp1;
                tail=temp1;

                temp1=next1;
                temp2=next2
            }
        }
        if(temp1 ==null) tail.next=temp2;
        if(temp2 ==null) tail.next=temp1;

        return NewHead;
    }

单链表循环队列是一种基于单链表实现的队列数据结构,可以实现先进先出的数据存储和读取。它的特点是队列的首尾节点相连,形成一个环形结构,队列的头指针和尾指针都指向环形结构上的某个节点,可以循环利用已经出队的节点。 下面是一个简单的单链表循环队列的实现过程: 1. 定义队列的结构体,包括头指针、尾指针和队列长度等信息。 ```c typedef struct queueNode { int data; struct queueNode *next; }QueueNode; typedef struct { QueueNode *head; QueueNode *tail; int size; }Queue; ``` 2. 初始化队列,将头指针和尾指针指向同一个节点,即创建一个空的链表。 ```c void initQueue(Queue *queue) { queue->head = (QueueNode *)malloc(sizeof(QueueNode)); queue->tail = queue->head; queue->head->next = NULL; queue->size = 0; } ``` 3. 判断队列是否为空。 ```c bool isEmpty(Queue *queue) { return queue->size == 0; } ``` 4. 判断队列是否已满,由于单链表循环队列的长度是固定的,因此只需要判断队列长度是否达到上限即可。 ```c bool isFull(Queue *queue) { return queue->size == MAX_QUEUE_SIZE; } ``` 5. 元素入队,将新元素插入到队列的尾部。 ```c void enQueue(Queue *queue, int data) { if (isFull(queue)) { printf("Queue is full!\n"); return; } QueueNode *newNode = (QueueNode *)malloc(sizeof(QueueNode)); newNode->data = data; newNode->next = NULL; queue->tail->next = newNode; queue->tail = newNode; queue->size++; } ``` 6. 元素出队,将队列的头部元素删除并返回。 ```c int deQueue(Queue *queue) { if (isEmpty(queue)) { printf("Queue is empty!\n"); return -1; } QueueNode *temp = queue->head->next; int data = temp->data; queue->head->next = temp->next; if (queue->tail == temp) { queue->tail = queue->head; } free(temp); queue->size--; return data; } ``` 7. 获取队列的长度。 ```c int size(Queue *queue) { return queue->size; } ``` 8. 清空队列,将队列中的所有元素删除。 ```c void clear(Queue *queue) { while (!isEmpty(queue)) { deQueue(queue); } } ``` 以上就是单链表循环队列的基本实现过程。需要注意的是,在每次出队操作时,需要判断队列中是否只有一个元素,若是,则需要将尾指针指向头指针。同时,由于单链表循环队列的长度是固定的,因此在插入新元素时需要判断队列是否已满。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值