链表

单向链表的基本说明

链表是一种物理存储单元上非连续、非顺序的存储结构数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表双向链表以及循环链表。链表可以在多种编程语言中实现。像Lisp和Scheme这样的语言的内建数据类型中就包含了链表的存取和操作。程序语言或面向对象语言,如C,C++和Java依靠易变工具来生成链表。

注:来源百度

代码实现

创建node

首先创建一个类node,其中一个用于存储数据,另一个用于存储下一个节点node

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 链表
public class node {

public int date; // 数据;

public node next; // 指针下一个节点;
// 默认为null
public node () {

}

public node (int value) {
this.date = value;
}

public node (int value,node next) {
this.date = value;
this.next = next;
}
}

创建一个linklist,并且定义一个head,通过访问head即可访问到整个链表.

1
2
3
4
5
6
7
8
public class Linklist {
public node head;// 定义一个头节点


public Linklist() {
this.head = null;
}
}
插入元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void insert (int value) {
node newnode = new node(value); // 用一个node来放value得值
node temp = head; // 临时节点
if (head == null) {
head = newnode;
return ;
}
while (temp.next != null) {
temp = temp.next;
}
// 此时得temp为最后一个节点 包括此时头节点.next为null得情况

// 放入最后元素
temp.next = newnode;



}
遍历链表
1
2
3
4
5
6
7
8
9
10
// 遍历链表
public void print_() {
node temp = head;
while (temp != null)
{
System.out.println("date:"+temp.date);
temp = temp.next;
}
}

链表长度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 链表长度
public int len () {
int cnt = 0;
node temp = head ;

while (temp != null) {
cnt++;
temp = temp.next;
}
return cnt;
}
// 长度
public void print_len() {
System.out.println("链表的长度是:"+len());
}
指定位置插入元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 在指定位置插入元素
public void insert_index (int index,int value) {
node curnode = head;

if (index == 0) {
node newnode = new node(value);
head = newnode;
head.next = curnode;
return ;
// 第一个位置
}

int pos = 1; // 记录当前位置
while (curnode != null ) {
if (pos == index) {
node newnode = new node(value);
newnode.next = curnode.next;
curnode.next = newnode;
return ;
}
curnode =curnode.next ;
pos++;
}
// while 结束表示index超过了链表本身的长度
System.out.println("index超出");

}
删除第index节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 删除指定第index节点
public void remove (int index) {
if (index < 1 ) {
return ;
}
if (index == 1) {
head = head.next;
return ;
}
// index > 1
int pos = 1;
node temp = head; // 定义temp为当节点的前一句节点
node curnode = head.next; // 定义当前节点

while (curnode != null) {
if (pos == index) {
temp.next = curnode.next;
return ;
}else {
temp = curnode;
curnode = curnode.next;
pos++;
}

}
//while 结束则证明未在链表中找到所需要删除的那个元素
System.out.println("未找到所删除的节点");
}

未完…….

简单测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
// TODO Auto-generated method stub
Linklist list = new Linklist();
list.insert(3);
list.insert(0);
list.insert(6);
// list.print_();
list.print_len();
list.insert_index(2, 5);
list.insert_index(0, 7);
list.insert_index(6, 0);
list.remove(3);
list.print_();

}
输出结果

链表的长度是:3
index超出
date:7
date:3
date:0
date:6