Java实现带头结点的单链表



一、什么是单链表?

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据(逻辑地址相连,物理地址不相连)。

通俗来说,单链表就是一个个节点连接在一起,形成一个完整的链条,每个节点包含2部分,数据域,和一个指向下一个节点引用的指针next。

带头结点的单链表即在初始化时产生一个head结点,其data域和next域均为空。
在这里插入图片描述



二、带头结点单链表的实现

1、接口的定义:

interface Ilist{		//线性表的抽象数据Java接口
	public void clear();
	public boolean isEmpty();
	public int length();
	public Object get(int i) throws Exception;
	public void insert(int i, Object x) throws Exception;
	public void remove(int i) throws Exception;
	public int indexOf(Object x);
	public void display();
}

2、结点的定义:

class Node{
	static final int num = 0;
	public Object data;		//存放结点值
	public Node next;		//后继结点的引用
	public Node() {			//无参数时的构造函数
		this(null,null);
	}
	public Node(Object data) {	//带一个参数时的构造函数
		this(data, null);
	}
	public Node(Object data, Node next) {	//带两个参数时的构造函数
		this.data = data;
		this.next = next;
	}
}

3、创建单链表:

class LinkList implements Ilist{
	public Node head;
	public LinkList() {		//单链表的构造函数
		head = new Node();
	}
	//构造一个长度为n的单链表
	public LinkList(int n, boolean Order) throws Exception{
		this();
		if(Order)
			create1(n);
		else
			create2(n);
	}
}

4、插入元素:

public void insert(int i, Object x) throws Exception {
	Node p = head;
	int j = -1;
	while(p != null && j<i-1) {
		p = p.next;
		++j;
	}
	if(j>i-1 || p == null)
		throw new Exception("插入位置不合法");
	Node s = new Node(x);
	s.next = p.next;
	p.next = s;
}

5、用尾插法创建单链表:

public void create1(int n) throws Exception{
	Scanner sc = new Scanner(System.in);
	for(int j=0; j<n; j++)
		insert(length(), sc.next());
}

6、用头插法创建单链表:

public void create2(int n) throws Exception{
	Scanner sc = new Scanner(System.in);
	for(int j=0; j<n; j++)
		insert(0,sc.next());
}

7、清空单链表:

public void clear() {
	head.data = null;
	head.next = null;
}

8、判断单链表是否为空:

public boolean isEmpty() {
	return head.next == null;
}

9、返回单链表的长度:

public int length() {
	Node p = head.next;
	int length = 0;
	while(p != null) {
		p = p.next;
		++length;
	}
	return length;
}

10、返回指定位置的元素:

public Object get(int i) throws Exception {
	Node p = head.next;
	int j = 0;
	while(p!=null && j<i) {
		p = p.next;
		++j;
	}
	return p.data;
}

11、删除指定位置的元素:

public void remove(int i) throws Exception {
	Node p = head;
	int j = -1;
	while(p.next != null && j<i-1) {
		p = p.next;
		++j;
	}
	if(j>i-1 || p.next == null)
		throw new Exception("删除位置不合法");
	p.next = p.next.next;
}

12、返回指定元素的位置:

public int indexOf(Object x) {
	Node p = head.next;
	int j=0;
	while(p!=null && !p.data.equals(x.toString())) {
		p = p.next;
		++j;
	}
	if(p != null)
		return j;
	else
		return -1;
}

13、遍历输出元素:

public void display() {
	Node node = head.next;
	while(node != null) {
		System.out.print(node.data + " ");
		node = node.next;
	}
	System.out.println();
}


附上全部代码:

import java.util.Scanner;

class Node{
	static final int num = 0;
	public Object data;		//存放结点值
	public Node next;		//后继结点的引用
	public Node() {			//无参数时的构造函数
		this(null,null);
	}
	public Node(Object data) {	//带一个参数时的构造函数
		this(data, null);
	}
	public Node(Object data, Node next) {	//带两个参数时的构造函数
		this.data = data;
		this.next = next;
	}
}
class LinkList implements Ilist{
	public Node head;
	public LinkList() {		//单链表的构造函数
		head = new Node();
	}
	//构造一个长度为n的单链表
	public LinkList(int n, boolean Order) throws Exception{
		this();
		if(Order)
			create1(n);
		else
			create2(n);
	}
	
	//用尾插法顺序建立单链表
	public void create1(int n) throws Exception{
		Scanner sc = new Scanner(System.in);
		for(int j=0; j<n; j++)
			insert(length(), sc.next());
	}
	
	//用头插法顺序建立单链表
	public void create2(int n) throws Exception{
		Scanner sc = new Scanner(System.in);
		for(int j=0; j<n; j++)
			insert(0,sc.next());
	}
	
	@Override
	public void clear() {
		head.data = null;
		head.next = null;
	}

	//构造判断单链表是否为空函数
	public boolean isEmpty() {
		return head.next == null;
	}

	//构造返回单链表长度的函数
	public int length() {
		Node p = head.next;
		int length = 0;
		while(p != null) {
			p = p.next;
			++length;
		}
		return length;
	}

	//构造查找单链表某位置上的元素
	public Object get(int i) throws Exception {
		Node p = head.next;
		int j = 0;
		while(p!=null && j<i) {
			p = p.next;
			++j;
		}
		return p.data;
	}

	//构造插入函数
	public void insert(int i, Object x) throws Exception {
		Node p = head;
		int j = -1;
		while(p != null && j<i-1) {
			p = p.next;
			++j;
		}
		if(j>i-1 || p == null)
			throw new Exception("插入位置不合法");
		Node s = new Node(x);
		s.next = p.next;
		p.next = s;
	}

	//构造删除函数
	public void remove(int i) throws Exception {
		Node p = head;
		int j = -1;
		while(p.next != null && j<i-1) {
			p = p.next;
			++j;
		}
		if(j>i-1 || p.next == null)
			throw new Exception("删除位置不合法");
		p.next = p.next.next;
	}

	//构造查找单链表上某值的位置
	public int indexOf(Object x) {
		Node p = head.next;
		int j=0;
		while(p!=null && !p.data.equals(x.toString())) {
			p = p.next;
			++j;
		}
		if(p != null)
			return j;
		else
			return -1;
	}

	//构造输出函数
	public void display() {
		Node node = head.next;
		while(node != null) {
			System.out.print(node.data + " ");
			node = node.next;
		}
		System.out.println();
	}
}

public class Task_1_2 {

	public static void main(String[] args) throws Exception {
		
		Scanner in = new Scanner(System.in);
		System.out.print("输入单链表的长度:");
		int n = in.nextInt();
		
		LinkList L = new LinkList();
		System.out.print("用头插法输入单链表个元素的值:");
		L.create2(n);
		System.out.print("输出此时单链表各元素的值:");
		L.display();
		
		L.insert(3,3);
		System.out.print("输出插入元素'3'后的单链表:");
		L.display();
		
		L.remove(4);
		System.out.print("输出删除元素'4'后的单链表:");
		L.display();
		
		System.out.print("输入要查找的位置:");
		int m = in.nextInt();
		if(m>L.length() || L.get(m)==null) 
			System.out.println("该元素不存在!");
		else
			System.out.println("查找的位置上的值:" + L.get(m));
		
		System.out.print("输入要查找的值:");
		int k = L.indexOf(in.nextInt());
		if(k!=-1)
			System.out.println("查找的值所在的位置:" + k);
		else
			System.out.println("该元素不存在!");
	}
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值