2、链表

2、链表


1、简介

​ 链表是一种物理存储单元上非连续、非顺序的存储结构数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。

​ 使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s6E6tI1q-1608815080744)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201215205226359.png)]

链表有很多种不同的类型:单向链表双向链表以及循环链表

2、创建结点类

package linkedList;
/**
 * @author Administrator
 *		结点类
 */
public class Node {
	//1、定义数据域,存放结点数据值
	public Object data;
	//2、定义指针域,存放后继结点
	public Node next;
	
	//无参构造函数
	public Node() {
		
	}

	//有参构造函数
	public Node(Object data, Node next) {
		super();
		this.data = data;
		this.next = next;
	}
	
	
}

3、创建单链表

package linkedList;

import java.util.Scanner;

import sqList.IList;

/**
 * @author Administrator 单链表描述类
 */
public class LinkedList implements IList {

	// 1、定义头结点
	public Node head;

	// 2、初始化头结点
	public LinkedList() {
		head = new Node();
	}

//	// 构造函数构造长度为n的单链表
//	public LinkedList(int n, boolean Order) {
//		this();
//		if (Order)
//			create1(n);
//		else
//			create1(n);
//	}

//	// 头插法(逆序)建立单链表
//	public void create1(int n) {
//		Scanner scanner = new Scanner(System.in);
//		for (int i = 0; i < n; i++) {
//			insert(i, scanner.next());
//		}
//
//	}
//
//	// 尾插法(顺序)建立单链表
//	public void create2(int n) throws Exception{
//		Scanner scanner = new Scanner(System.in);
//		for (int i = 0; i < n; i++) {
//			insert(length(), scanner.next());
//		}
//	}

	@Override
	public void clear() {
		// 将头结点置空,后继结点置空
		head.data = null;
		head.next = null;
	}

	@Override
	public boolean isEmpty() {
		// 判断头结点是否有后继结点即可
		return head.next == null;
	}

	@Override
	public int length() {
		// 遍历单链表,返回长度
		// 定义长度
		int length = 0;
		// p 为后继结点
		Node p = head.next;
		while (p != null) {
			p = p.next;
			length++;
		}
		return length;
	}

	@Override
	public Object get(int i) {
		// 定义后继结点
		Node p = head.next;
		int j;
		// 遍历链表
		for (j = 0; j < i && p != null; j++) {
			p = p.next;
		}
		// 如果是空表或已经越过了 i
		if (j > i | p == null) {
			System.out.println("查找错误!");
		}
		return p.data;
	}

	// 带头节点的插入
	@Override
	public void insert(int i, Object x) {
		Node p = head;
		// 考虑到插入位置可能是链表头
		int j = -1;
		// 寻找i位置的前驱结点(第 i-1 个结点)
		while (p != null && j < i - 1) {
			p = p.next;
			j++;
		}
		// 判断插入位置合法性
		if (j > i - 1 | p == null) {
			System.out.println("插入位置不合法!");
		}
		// 建立要插入的新结点
		Node n = new Node();
		n.data = x;
		n.next = p.next;
		p.next = n;
	}

	@Override
	public void remove(int i) {
		Node p = head;
		int j = -1;
		// 寻找i位置的前驱结点(第 i-1 个结点)
		while (p != null && j < i - 1) {
			p = p.next;
			j++;
		}
		if(j > i - 1 | p == null) {
			System.out.println("删除位置不合法!");
		}
		p.next = p.next.next;
	}

	@Override
	public int indexOf(Object x) {
		Node p = head;
		// 定义一个游标
		int tp = 0;
		while (p != null && p.data.equals(x)) {
			p = p.next;
			tp++;
		}
		if (p != null)
			return tp;
		else
			return -1;
	}

	@Override
	public void display() {
		Node p = head;
		while (p != null && p.next !=null) {
			p = p.next;
			System.out.println(p.data);
		}
		

	}

}

4、创建测试类

package linkedList;

/**
 * @author Administrator 测试类
 */
public class Test {

	public static void main(String[] args) {
		LinkedList linkedList = new LinkedList();
		// 判断是否空链表,链表长度
		System.out.println(linkedList.isEmpty());
		System.out.println(linkedList.length());
		// 插入结点
		linkedList.insert(0, "徐凤年");
		linkedList.insert(1, "青鸟");
		linkedList.insert(2, "红麝");
		linkedList.insert(3, "绿蚁");
		linkedList.insert(4, "姜泥");
		linkedList.insert(2, "洛阳");
		// 判断是否插入成功
		System.out.println(linkedList.isEmpty());
		System.out.println(linkedList.length());
		// 按位置查找
		System.out.println(linkedList.get(3));
		// 按值查找

		// 删除结点
		linkedList.remove(1);
		// 判断是否删除成功
		System.out.println(linkedList.length());
		linkedList.display();
		
//		//头插法
//		linkedList.create1(2);
		

	}

}

5、总结

  1. 链表动态分配存储空间,能避免资源浪费,提高运行效率和存储空间利用率。
  2. 链表便于插入和删除。
  3. 不能按照位号随机存取。

6、顺序存储和链式存储的比较

顺序表链表
缺点存储空间预先分配,容易造成资源浪费。插入和删除效率低。存储密度低。不能随机存取。
优点可进行高效随机存取。存储密度高。插入和删除效率高。进行动态的存储空间分配。
缺点
优点
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值