码迷,mamicode.com
首页 > 其他好文 > 详细

链表、队列、栈

时间:2020-11-01 10:43:33      阅读:20      评论:0      收藏:0      [点我收藏+]

标签:tno   ||   system   sdn   设置   copy   基础   mic   消息   

一、单链表

所谓单链表(Linked)在内存中不连续的一段内存空间,链表的每一个元素是一个节点,每一个节点由数据元素和下一个节点的存储位置组成,链表结构与数组结构最大区别是链表结构的存储内存是不连续的,而数组结构的内存是连续的,链表结构不能与数组结构一样快速查找

? 链表机构操作特点是:添加,删除元素效率高,查询效率低;
? 数组结构特点:添加,删除效率低,查询效率高

链表结构的示意图
技术图片
前驱:该节点的上一个元素的地址

后继:该节点的下一个元素的地址

链表结构中最后一个元素的“后继”为null

public class MyLinked {
    //链表中有节点属性
    Node header;//度过有一个节点,name这个节点就是头结点
    int size;//链表节点的大小

    //节点类 包括节点的数据内容和下一个节点的地址
    class Node<T>{
        //表示节点数据内容
        T data;
        //下一个节点的地址
        Node next;
        public Node(T data){
            this.data=data;
        }

        public T getData(){
            return data;
        }
        public void setData(T data){
            this.data=data;
        }
        public Node getNext(){
            return next;
        }
        public void setNext(Node next){
            this.next=next;
        }
    }

链表实现添加元素
技术图片

/**
 *将元素添加到第一个节点
 */
 public void addFirst(Object obj){
      //创建节点
      Node node=new Node(obj);
      //整体要求:将当前链表的头结点变更为新节点
      //新节点中的后继是原始头节点
      node.next=this.header;
      //将头节点变更
      this.header=node;
      //长度加1
      this.size++;
 }
/**
 *添加到最后
 */
 public void addLast(Object obj){
      Node node=new Node(obj);
      //找到最后一个节点
      Node lastNode=this.header;
      while(lastNode.next!=null){
       lastNode=lastNode.next;
      }
      lastNode.next=node;
      this.size++;
 }
/**
 *将元素添加到指定下标
 */
 public void add(Object obj,int index){
      Node node=new Node(obj);
      //验证index的范围
      if(index<0||index>this.size){
        throw new IndexOutOfBoundsException("下标越界,index不在此链表中");
      }
      //查找指定位置的节点(前一个节点的地址 和当前节点的地址)遍历index-1遍
      //前一个节点
      Node pre=this.header;
      //当前下标的节点
      Node cur;
      for(int i=0;i<index-1;i++){
            pre=pre.next;
      }
      cur=pre.next;
      pre.next=node;
      node.next=cur;
      this.size++;
 }

链表实现删除元素
技术图片


/**
 * 删除第一个节点
 */
 public void removeFirst(){
      //删除第一个节点
      if(this.size==0){
            throw new IllegalArgumentException("没有可删除的元素")
      }
      //让当前节点的“后继”作为头结点
      this.header=header.next;
      this.size--;
 }
/**
 *删除第一个节点
 */
 public void removeLast(){
      //删除是否存在数据
      if(this.size==0){
            throw new IllegalArgumentException("没有需要删除的元素");
      }
      //找到最后一个元素的前一个地址,并将该地址的next改为null
      Node pre=this.header;
      Node cur=this.header;
      while(pre.next!=null){
           pre=cur;
            cur=cur.next;
      }
      //最后一个元素 就是 当前
      pre.next=null;
      size--;
 }

链表实现根据下标 获取指定的节点

/**
 *根据下标 获取指定的节点
 */
 public Node getByIndex(int index){
      if(this.size==0){
            throw new IllegalArgumentException("没有需要查找的元素");
      }
      if(index==0){
            return this.header;
      }
      //查找指定下标的元素
      Node cur=this.header;//从第一个元素开始
      int j=0;
      while(index!=j&&index<this.size){
            //依次往下一个元素查找
            cur=cur.next;
            j++;
      }
      return cur;
 }
      puclic int getSize(){
            return size;
      }
 

2、队列结构

队列结构:基于链表结构的基础上,实现一种“先进先出”的结构,常用操作 入队(put),出队(pop),设置队列的头节点和尾节点
技术图片

public class MyQueue <T>{
    //头结点
    private Node front;
    //尾节点
    private Node tail;
    //大小
    private int size;

    public MyQueue() {
        //头,尾为空
        this.front=this.tail=null;
    }
    class Node{
        private T obj;
        private Node next;

        public Node(T obj) {
            this.obj = obj;
        }

        public T getObj() {
            return obj;
        }

        public void setObj(T obj) {
            this.obj = obj;
        }

        public Node getNext() {
            return next;
        }

        public void setNext(Node next) {
            this.next = next;
        }
    }
    /**
     * 入队:将元素添加到队列的尾部
     */
    public void put(T obj){
        //创建节点
        Node node=new Node(obj);
        //如果元素为空 则头就是尾,尾就是头
        if (isEmpty()){
            this.front=this.tail=node;
            return;
        }
        //将新元素的地址 作为尾的next
        this.tail.next=node;
        //将新元素的节点  作为尾节点
        this.tail=node;

        this.size++;
    }
    /**
     * 出队:将元素从队列的头部移除(保持与队列脱离关系)
     */
    public T pop(){
        if (isEmpty()){
            throw new IllegalArgumentException("没有弹出的元素");
        }
        //移除头部元素
        Node popNode=this.front;
        //设置现在的头元素是下一个
        this.front=popNode.next;
        //将弹出的元素next设置为null,与队列脱离关系
        popNode.next=null;
        this.size--;
        //如果没有了素了 则需要设置头尾都是null
        if(this.size<0){
            this.front=this.tail=null;
        }
        return popNode.getObj();
    }
    /**
     * 判断元素是否为空
     */
    public boolean isEmpty(){
        if (this.front==null&&this.tail==null){
            return true;
        }
        return false;
    }
}

3、栈结构

栈(Stack)结构也是常用数据结构之一,它具有“后进先出”的特点
技术图片

public class MyStack<T> {
    //定义一个数组,用于存储元素
    private Object[] obj;
    private int size;

    public MyStack() {
        obj=new Object[10];
        size=0;
    }
      
}
 /**
     * 入栈:假如栈元素
     */
    public void push(T t){
        expandCapacity(size+1);
        obj[size]=t;
        size++;
    }

    /**
     * 返回栈顶元素:peek
     */
    public T peek(){
        if (size>0){
            return (T)obj[size-1];
        }
        return null;
    }
    /**
     * 出栈:返回栈顶元素,并删除该元素
     */
    public T pop(){
        T t=peek();
        if (size>0){
            //将最后一个元素 删除
            obj[size-1]=null;
            size--;
        }
        return t;
    }
    /**
     * 是否为空元素
     */
    public boolean isEmpty(){
        return size==0;
    }
    /**
     * 数组扩容大小:1.5倍
     */
    public void expandCapacity(int size){
        if (obj.length<size){
            //需要扩容
            int length=size*3/2 +1;
            this.obj= Arrays.copyOf(this.obj,length);
        }
    }
}

测试

public class TestStack {
    public static void main(String[] args) {
        //创建栈
        MyStack<String> stack=new MyStack<>();
        stack.push("hello1");
        stack.push("hello2");
        stack.push("hello3");
        //返回栈顶
        System.out.println(stack.peek());
        //出栈并删除
        stack.pop();
        System.out.println(stack.peek());

        //最常见的栈应用  递归函数调用
        // 队列的应用:消息队列,订阅,线上排队买票
    }
}

链表、队列、栈

标签:tno   ||   system   sdn   设置   copy   基础   mic   消息   

原文地址:https://www.cnblogs.com/zzk201/p/13883950.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!