一、什么是单链表?
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据(逻辑地址相连,物理地址不相连)。
通俗来说,单链表就是一个个节点连接在一起,形成一个完整的链条,每个节点包含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("该元素不存在!");
}
}
运行结果: