左神算法基础5-链表——哈希表、有序表、单链表和双链表

一、哈希表

在这里插入图片描述

  • 内部按值传递
  public static void main(String[] args) {
   
        HashMap<String,String> mapTest = new HashMap<>();
        mapTest.put("cscsdv","zuo");//cscsdv有多大,拷贝一份放到哈希表里
        //如果你的某个key特别长的话,哈希表一定使用空间很多,
        //它是内部按照值传递的
        mapTest.put("czdvvsdv","cheng");
        mapTest.put("sdvsv","yun");


    }
  • 内部按引用传递
    -(比如申请的是一个Node类型)
  public class Node{
   
        public int value;
        public Node next;
        //.......
        //node很多,开辟的很大
        //但是它不会影响哈希表内存

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

在这里插入图片描述
nodeA和nodeB的地址不同,两个放在哈希表里,不是一个东西
虽然两个内部值看起来一样,但是哈希表不是按内部值传递的

在这里插入图片描述

   public static void main(String[] args) {
   
        HashMap<Integer,String> mapTest = new HashMap<>();
        //增加键值
        mapTest.put(1,"number6");
        //修改值
        mapTest.put(1,"number1")
       //1、查询
        mapTest.containsKey(1);
        //2、同时把key对应的value拿出来
        mapTest.get(1);
        //删除
        mapTest.remove(1);

    }

!!哈希表在使用的时候,时间复杂度都是常数级别
增删改查都是常数级别

二、有序表

在这里插入图片描述

  • 不提供比较器(报错)

  • 在这里插入图片描述

  • 提供比较器
    在这里插入图片描述
    在这里插入图片描述

  • code:

  • 在这里插入图片描述

题目1:反转单向链表

1.分析

(1)单向链表节点结构

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

在这里插入图片描述

2.完整代码

//反转单链表
public class ReverseLinkedList {
   
	//单链表结构
	public static class Node {
   
		public int value;
		public Node next;

		public Node(int value) {
   
			this.value = value;
		}
	}
	public static Node reverseLinkedList(Node head) {
   
		if(head == null){
   
			return null;
		}
		//一定要注意:
		//pre一直代表遍历到要反转节点的前驱节点
		//next一直代表遍历到要反转节点的后继节点
		Node pre = null; 
		Node next = null;
		while(head != null){
   
			//先用next保存head的下一个节点的信息
            //保证单链表不会因为反转head节点的原next节点而就此断裂
			next = head.next;
			//反转,head的后继变成向前指,指向head的next前驱
			head.next = pre;
			//节点的前驱和节点都后移,继续遍历
			pre = head;
			head = next;
		}
		//如果head为null的时候,pre就为最后一个节点了,就此链表已经反转完毕,pre就是反转后链表的第一个节点
		return pre;
	}
}


题目2:反转双向链表

1.分析

(1)双向链表节点结构

 public class DoubleNode{
   
        public int value;
        public DoubleNode next;//往后指的指针
        public DoubleNode last;//往前指的指针
        
        public DoubleNode(int data){
   value = data;}
    }

2.完整代码

public static DoubleNode reverseDoubleLinkedList(DoubleNode head) {
   
		if(head == null){
   
			retrun null;
		}
		
		DoubleNode next = null;
		//pre的作用仅仅是记录head的上一个节点
		DoubleNode pre = null;
		
		while(head != null) {
   
			//先用next保持后继节点,然后交换前后节点
			next = head.next;
			head.next = pre;
			head.last = next;
			//记录pre
			pre = head;
			//head指向tmp保存的原节点的后继节点,即向后推进一个节点
			head = next;
		}
		return pre;
	}

题目3:给定两个有序链表的头指针head1和head2,打印两个链表的公共部分(要求:两个链表长度和为N,时间复杂度为O(N),空间复杂度为O(1))

1.完整代码

public class PrintCommonPart {
   
    public static class Node{
   
        public int value;
        public Node next;
        public Node(int data){
   this.value = data;}
    }
    public static void printCommonPart(Node head1,Node head2){
   
        System.out.println("Common Part: ");
        while (head1 != null && head2 != null){
   
            //谁小谁移动
            if(head1.value < head2.value){
   
                head1 = head1.next;
            }else if(head1.value > head2.value){
   
                head2 = head2.next;
            }else{
   //相等就打印
                System.out.print(head1.value+" ");
                //打印之后,都移动
                head1 = head1.next;
                head2 = head2.next;

            }

        }
        System.out.println();
    }
    public static void printLinkedList(Node node){
   
        System.out.print("LinkedList:");
        while (node!=null){
   
            System.out.print(node.value+" ");
            node = node.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
   
        Node node1 = new Node(2);
        node1.next = new Node(3);
        node1.next.next = new Node(5);
        node1.next.next.next = new Node(6);

        Node node2 = new Node(1);
        node2.next = new Node(2);
        node2.next.next = new Node(5);
        node2.next.next.next = new Node(7);
        node2.next.next.next.next = new Node(8);
        printLinkedList(node1);
        printLinkedList(node2);
        printCommonPart(node1,node2);

    }
}

栈和队列

1、栈和队列

在这里插入图片描述

(1)双向链表实现

在这里插入图片描述

  • 头部为空

在这里插入图片描述)

  • -头部不为空,加入4
    在这里插入图片描述
package zuoshen.class04;
//用双向链表实现队列
public class Queue {
   
    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;

        //1、给用户提供一个在头部加头结点的方法
        public void addFromHead(T value){
   //加一个值3
            Node<T> cur = new Node<T>(value);
            if(head == null){
   
                head = cur;
                tail = cur;
            }else{
   //3已经在队列,加入4
                cur.next = head;
                head.last = cur;

                //当前结点做头
                head = cur;

            }
        }
        //2、给用户提供一个在尾部加结点的方法
        public void addFromBottom(T value){
   //加一个值3
            Node<T> cur = new Node<T>(value);
            if(head == null){
   
                head = cur;
                tail = cur;
            }else{
   //3已经在队列,加入4
                cur.last = tail;
                tail.next = cur;
                tail = cur;
            }
        }
        //3、给用户提供一个在头部弹出结点的方法
        public T popFromHead(){
   
            //一个数什么也没有,就给用户返回空了
            if(head == null){
   
               return null;
            }
            Node
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值