数据结构之单向链表与双向链表-简单介绍与练习

数据结构之单向链表与双向链表-简单介绍与练习


1. 单向链表

  • 单向链表中,前一个节点保存着下一个节点的内存地址,下一个节点保存着下下个节点的内存地址,… ,最后一个节点后指向null

  • 单向链表在数据的搜寻过程中,只能按顺序单向执行下去

  • 创建一个单向链表,一般返回的是头部节点,因为利用头部节点可以顺着单向链获得其他所有节点

  • 单向链表节点结构(可实现成泛型):

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

2. 双向链表

  • 双向链表中,一个节点保存着前后相邻节点的内存地址,头节点和尾节点的前后分别指向null

  • 双向链表在数据的搜寻过程中,能任意进行搜寻方向前后的变化

  • 双向链表节点结构(可实现成泛型):

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

3. 单向链表和双向链表最简单的练习

所使用的链表结构与前面的展示的单双链表节点结构相同

1. 单链表和双链表如何反转

  • 代码实现:

    public static Node reverseLinkList(Node head) {
    	Node pre = null; // 保存前一节点的值
    	Node next = null; // 保存后一节点的值
    	while(head != null) {
    		next = head.next;
    		head.next = pre;
    		pre = head;
    		head = next;
    	}
    }
    public static DoubleNode reverseDoubleList(DoubleNode head) {
    	DoubleNode pre = null; // 保存前一节点的值
    	DoubleNode next = null; // 保存后一节点的值
    	while(head != null) {
    		next = head.next;
    		head.next = pre;
    		head.pre = next;
    		pre = head;
    		head = next;
    	}
    }
    

2. 把单链表或双链表中的指定值都删除

  • 代码实现:

    // 单链表的指定值都删除
    public static Node removeLinkListValue(Node head, int num) {
    	while(head != null) {
    		// 如果头部直接是要删的值,直接丢弃,没有其他引用会自动释放
    		if(head.value == num) { // 找到要删的值
    			head = head.next;
    		}else {
    			break;
    		}	
    	}
    	// 头部的值不是要删的,所以后面遇到要删的,丢弃后还要将下一节点与上一节点相连
    	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 static DoubleNode removeDoubleListValue(DoubleNode head, int num) {
    	while(head != null) {
    		// 如果头部是要删的值,head直接跳到后一个节点,
    		// 并将此时的前一个节点指向null,要删的值没有其他引用会自动释放
    		if(head.value == num) {
    			head = head.next;
    			head.pre = null;
    		}else {
    			break;
    		}
    	}
    	// 此时头部不是要删的值,所以后面遇到要删的,丢弃后还要将下一节点与上一节点相连,要删的值没有其他引用会自动释放
    	Node pre = head; // 保存前一节点的值
    	Node cur = head; // 保存当前节点的值,避免原始头部丢失
    	while(cur != null) {
    		if(cur.value == num) { // 找到要删的值
    			pre.next = cur.next; // 断开前一项的next对其的引用
    			if(cur.next != null) { // 如果要删的值的后一项不为空
    				cur.next.pre = pre; // 断开后一项pre对其的引用
    			}else {
    				// 如果后一项已经为空,可以直接结束了
    				break;
    			}
    		}else {
    			pre = cur;
    		}
    		cur = cur.next;
    	}
    	return head;
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值