3.链表(Linked List)

 1.基本结构

链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的
  2.前期准备

一个Node里面包含一个元素(element)和一个结点(node<E>):

   private Node<E> first;  // 创建头节点
   private E element;      // 元素
   pirvate Node<E> next;   // 下一个节点
//构造函数(创造Node)
public Node(E element, Node<E> next) {  
			this.element = element;
			this.next = next;
		}
// 边界条件
public void rangeCheck(int index) {
		if (index < 0 || index >= size) {
			throw new IndexOutOfBoundsException("索引越界");
		}
	}
 public void rangeCheckForAdd(int index) {
		if (index < 0 || index > size) {
			outOfBounds(index);
		}
	}
// 根据index获取对应的node<E>
private Node<E> node(int index) {
		rangeCheck(index);
		
		Node<E> node = first;   //创建头结点
		for (int i = 0; i < index; i++) {
			node = node.next;
		}
		return node;
	}

 3.代码实现

 // 清除操作
public void clear() {
		size = 0;   //size清零
		first = null;  //头尾结点指向空
		}
// 根据index获取元素
// 最好:O(1) 最坏:O(n) 平均:O(n)
public E get(int index){
		return node(index).elment;
	}
// 添加操作	
// 最好:O(1) 最坏:O(n) 平均:O(n)
public void add(int index,int element){
        rangeCheckforAdd(index);
		if(index==0){      // 如果插入的是头节点的话
			first = new Node<>(element,first);
		}
		else{
			Node<E> prev = node(index-1);  //发现尾节点符合要求,而头节点不符合
			prev.next= new Node<>(element,prev.next);
		}
		size++;
	}
// 删除操作
// 最好:O(1) 最坏:O(n) 平均:O(n)
	public void remove(int index){
        rangeCheck(index)
        Node<E> node = first;  //创造头节点
		if(index==0){
			first = first.next;
		}
		else{
			Node<E> prev = node(index-1);
			pre.next = prev.next.next;
		}
		size--;
	}
// 根据element找node
public int indexOf(E element){
		if(element==null){     //因为null中没有equals方法
			Node<E> node = first;
			for (int i = 0; i < size; i++) {
				if(node.element==null){
					return i;
				}
				node=node.next;
			}
		}
		else{
            Node<E> node = first;  //创建头节点
			for (int i = 0; i < size; i++) {
     				if(element.equals(node.element)){
					return i;
				}
				node=node.next;
			}
		}
		return -1;
	}

4.练习题

4.1 删除结点

// 删除结点
public void deleteNode(ListNode node){
		node.val= node.next.val;
		node.next=node.next.next;
	}

 4.2 反转链表

                                              

// 递归方法
public ListNode reverseList(ListNode head){
		// 如果没有结点或者只有一个结点,直接返回
		if(head==null || head.next=null) return  head;
		
		List newHead = reverseList(head.next);
		head.next.next=head;
		head.next=null;
		return newHead;
	}
// 迭代方法
 	public ListNode reverseList(ListNode head) {
		if (head == null || head.next == null) return head;
		
		ListNode newHead = null;  //创造一个newHead
		while (head != null) {
		    ListNode temp = head.next;   //防止被回收
            // 开始反转
			head.next = newHead;
			newHead = head;
			head = temp;       //为下一次迭代做准备
		}
	}

4.3 判断链表是否有环

	public boolean hasCycle(ListNode head){
		if(head==null||head.next==null) return false;
		
		ListNode slow = head;        // 创建慢指针
		ListNode fast = head.next;  //创建快指针
		
		while( fast!=null&&fast.next!=null ){
			if(slow==fast) return true;
			slow = slow.next;
			fast = fast.next.next;
		}
		return false;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值