数据结构与算法(3)—链表

在讨论链表(linked-list)之前,需要明确几个概念:线性表(顺序表, list, linear list), 数组(array),链表(linked-list)。

线性表:线性表也叫作顺序表,它是最基础、最简单、最常用的一种基本数据结构,线性表总存储的每个数据称为一个元素,各个元素及其索引是一一对应的关系。线性表有两种存储方式:顺序存储方式和链式存储方式。

数组(array):数组就是线性表的顺序存储方式。数组的内存是连续分配的,并且是静态分配的,即在使用数组之前需要分配固定大小的空间。可以通过索引直接得到数组中的而元素,即获取数组中元素的时间复杂度为O(1)。

链表(linked-list):链表就是线性表的链式存储方式。链表的内存是不连续的,前一个元素存储地址的下一个地址中存储的不一定是下一个元素。链表通过一个指向下一个元素地址的引用将链表中的元素串起来。

1.单向链表:

单向链表节点结构:

   

      data域:存储数据元素信息的域称为数据域

      next域:存储直接后继位置的域称为指针,它是存放节点的直接后继的地址(位置)的指针域

      data域+next域:组成数据ai的存储映射,称为节点

注意:链表通过每个节点的指针域将线性表的n个节点按其逻辑顺序连接在一起的

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

2.双向链表

双向链表节点结构

顾名思义,双向链表就是有两个方向的链表。同单向链表不同,在双向链表中每一个节点不仅存储指向下一个节点的指针,而且存储指向前一个节点的指针。通过这种方式,能够通过在O(1)时间内通过目的节点直接找到前驱节点,但是同时会增加大量的指针存储空间。

双向链表

 

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

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

3.单链表与双链表的简单coding练习

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

       遍历法:遍历法就是在链表遍历的过程中将指针顺序置换

    // head
	// a -> b -> c -> null
	// c -> b -> a -> null
	public static Node reverseListedList(Node head) {
		Node pre = null;
		Node next = null;
		while(head != null) {
			next = head.next;
			head.next = pre;
			pre = head;
			head = next;
		}
		return pre;
	}

  代码解析:例如:1->2->3->4

  • 准备两个空结点   pre用来保存先前结点、next用来做临时变量
  • 在头结点head遍历的时候此时为1结点
    • next = 1结点.next    (2结点)
    • 1结点.next=pre(null)
    • pre = 1结点
    • head = 2结点
  • 进行下一次循环head=2结点
    • next = 2结点.next    (3结点)
    • 2结点.next=pre(1结点)=>即完成2->1
    • pre = 2结点
    • head = 3结点
  • 进行循环...

双链表的反转:

    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;
	}

2)把给定值都删除

public class Code02_DeleteGivenValue {
	
	public static class Node{
		public int value;
		public Node next;
		
		public Node(int data) {
			this.value = data;
		}
	}
	
	//head = removeNode(head,2)
	public static Node removeNode(Node head,int num) {
		//head来到第一个不需要删除的位置
		while(head != null) {
			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;
	}

}

4.栈和队列 

逻辑概念 栈:数据先进后出,犹如弹匣

队列:数据先进先出,好似排队

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值