数据结构与算法:链表,队列,栈,递归,有序表

本文详细介绍了如何使用链表实现单链表和双链表的反转,以及如何用数组、链表、双端链表来实现栈和队列的操作。此外,还探讨了如何使用两个栈实现队列,以及如何用队列实现栈。最后,讨论了如何将递归转换为非递归,并提到了几种数据结构在信息技术领域的应用,如红黑树、AVL树等。
摘要由CSDN通过智能技术生成

反转单链表,双链表

import java.util.ArrayList;
import java.util.List;

public class ReverseList {

    public static class Node{
        public int value;
        public Node next;

        public Node(int data){
            value = data;
        }
    }

    public static class DoubleNode{
        public int value;
        public DoubleNode last;
        public DoubleNode next;

        public DoubleNode(int data){
            value = data;
        }
    }

    // 利用双指针,反转单链表
    // head   a - > b - > c - > d - > e - > null
    public static Node reverseLinkedList(Node head){
        Node pre = null;
        Node next = null;

        while(null != head){
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }

    // 反转双向链表
    public static DoubleNode reverseDoubleList(DoubleNode head){
        DoubleNode pre = null;
        DoubleNode next = null;
        while(head != null){
            next = head.next;
            head.next = pre;
            head.last = next;
            pre = head;
            head = next;
        }

        return pre;
    }

    public static Node testReverseLinkedList(Node head){
        if(null == head){
            return null;
        }

        ArrayList<Node> list = new ArrayList<>();
        while(head != null){
            list.add(head);
            head = head.next;
        }
        list.get(0).next = null;
        int N = list.size();
        for (int i = 1; i < N; i++) {
            list.get(i).next = list.get(i-1);
        }
        return list.get(N-1);
    }

    public static Node generateRandomLinkedList(int len, int value){
        int size = (int)(Math.random() * (len+1));
        if(size == 0){
            return null;
        }

        size--;
        Node head = new Node((int)(Math.random())*(value+1));
        Node pre = head;
        while(size != 0){
            Node cur = new Node((int)(Math.random())*(value+1));
            pre.next = cur;
            pre = cur;
            size--;
        }

        return head;
    }

    public static List<Integer> getLinkedListOriginOrder(Node head){
        List<Integer> ans = new ArrayList<>();
        while(head != null){
            ans.add(head.value);
            head = head.next;
        }

        return ans;
    }

    public static boolean checkLinkedListReverse(List<Integer> origin, Node head){
        for (int i = origin.size()-1; i >= 0 ; i--) {
            if(!origin.get(i).equals(head.value)){
                return false;
            }

            head = head.next;
        }

        return true;
    }

    public static void main(String[] args) {
        int len = 50;
        int value = 100;
        int testTime = 100000;
        System.out.println("test Begin!!");
        for (int i = 0; i < testTime; i++) {
            Node node1 = generateRandomLinkedList(len,value);
            List<Integer> list1 = getLinkedListOriginOrder(node1);
            node1 = reverseLinkedList(node1);
            if(!checkLinkedListReverse(list1,node1)){
                System.out.println("Oops1!");
            }

        }

        System.out.println("test end!!");
    }

// 删除链表中值等于num的节点
    public static Node removeValue(Node head, int num){
        while(null != head){
            // 来到第一个不需要删的位置
            if(head.value != num){
                break;
            }

            head = head.next;
        }

        Node pre = head;
        Node cur = head;
        while(cur != null){
            if(cur.value == num){
                pre.next = cur.next;
            }else{
                pre = cur;
            }
            cur = cur.next;
        }

        return head;
    }
}

队列和栈是逻辑上的概念

数组和链表都能实现队列和栈。

双端链表实现队列

public class DoubleEndsQueueToStackAndQueue {
    public static class Node<T>{
        public T value;
        public Node<T> last;
        public Node<T> next;

        public Node(T data){
            value = data;
        }
    }

    // 双端队列
    public static class DoubleEndsQueue<T>{
        public Node<T> head; // 头指针
        public Node<T> tail; // 尾指针

        // 从头部加
        public void addFromHead(T value){
            Node<T> cur = new Node(value);
            if(head == null){
                head = cur;
                tail = cur;
            }else{
                head.last = cur;
                cur.next = head;
                head = cur;
            }
        }

        // 从尾部加
        public void addFromBottom(T value){
            Node<T> cur = new Node(value);
            if(tail == null){
                head = cur;
                tail = cur;
            }else{
                tail.next = cur;
                cur.last = tail;
                tail = cur;
            }
        }

        // 从头部弹出来
        public T popFromHead(){
            if(head == null){
                return null;
            }
            Node<T> cur = head;
            if(head == tail){
                tail = null;
                head = null;
            }else{
                head = head.next;
                cur.next = null;
                head.last = null;
            }

            return cur.value;
        }

        // 从尾部弹出来
        public T popFromTail(){
            if(head == null){
                return null;
            }

            Node<T> cur = tail;
            if(head == tail){
                tail = null;
                head = null;
            }else{
                tail = tail.last;
                tail.next = null;
                cur.last = null;
            }

            return cur.value;
        }
    }

    public static void main(String[] args) {

    }
}

数组实现队列

public class RingArray {
    public static class MyQueue{
        private int[] arr;
        private int pushi;
        private int polli;
        private int size;        // 已加入到队列中的个数
        private final int limit; // 队列最多能装多少个

        public MyQueue(int limit){
            arr = new int[limit];
            pushi = 0;
            polli = 0;
            size = 0;
            this.limit = limit;
        }

        public void push(int value){
            if(size == limit){
                throw new RuntimeException("栈满了,不能再加了");
            }
            size++;
            arr[pushi] = value;
            pushi = nextIndex(pushi);
        }

        public int pop(int value){
            if(size == 0){
                throw new RuntimeException("栈空了,不能再拿了");
            }
            size--;
            int cur = arr[polli];
            polli = nextIndex(polli);
            return cur;
        }

        public boolean isEmpty(){
            return size == 0 ? true : false;
        }

        // 如果现在的下标值是i,返回下一个位置
        public int nextIndex(int i){
            // 如果没到底,位置就加1。 如果位置到底,就返回0
            return i < limit - 1 ? i+1 : 0;
        }
    }
}

实现一个特殊的栈,在实现基本功能的基础上,再实现返回栈中最小元素的功能

  1. pop,push,getMin操作的时间复杂度都是O(1)
  2. 设计的栈类型可以使用现成的栈结构

题目: 如何用栈结构实现队列结构

import java.util.Stack;

public class TwoStacksImplementQueue {

    public static class TwoStacksQueue{
        public Stack<Integer> stackPush;
        public Stack<Integer> stackPop;

        public TwoStacksQueue(){
            stackPush = new Stack<Integer>();
            stackPop = new Stack<Integer>();
        }

        //  从push栈往pop栈倒入数据
        private void pushToPop(){
            if(stackPop.empty()) { // 只有pop栈不为空
                while (!stackPush.isEmpty()) {
                    stackPop.push(stackPush.pop());
                }
            }
        }

        public void add(int pushInt){
            stackPush.push(pushInt);
            pushToPop();
        }

        public int poll(){
            if(stackPush.empty() && stackPop.empty()){
                throw new RuntimeException("Queue is empty");
            }

            pushToPop();
            return stackPop.pop();
        }

        public int peek(){
            if(stackPush.isEmpty() && stackPop.isEmpty()){
                throw new RuntimeException("Queue is empty");
            }
            pushToPop();
            return stackPop.peek();
        }
    }

    public static void main(String[] args) {

    }
}

题目: 如何用队列结构实现栈结构

package datastructure.trainingcamp.Code03;

import java.util.LinkedList;
import java.util.Queue;

public class TwoQueueImplementStack {
    public static class TwoQueueStack<T>{
        public Queue<T> queue;
        public Queue<T> help;

        public TwoQueueStack(){
            queue = new LinkedList<>();
            help = new LinkedList<>();
        }

        public void push(T value){
            queue.offer(value);
        }

        public T poll(){
            while(queue.size() > 1){
                help.offer(queue.poll());
            }

            T ans = queue.poll();
            Queue<T> tmp = queue;
            queue = help;
            help = tmp;
            return ans;
        }

        public T peek(){
            while(queue.size() > 1){
                help.offer(queue.poll());
            }

            T ans = queue.poll();
            help.offer(ans);

            Queue<T> tmp = queue;
            queue = help;
            help = tmp;
            return ans;
        }
    }

    public static void main(String[] args) {

    }
}

任何递归都可以改成非递归

红黑树,avl,sb树,跳表都能实现有序表。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值