注:定义来源于
《数据结构(C++版)(王红梅/胡明/王涛 编著)》 第2版。
线性表是一种最基本、最简单的数据结构,数据元素之间仅具有单一的前驱和后继关系。
线性表(linear list)简称表,是n(n>=0)个具有相同类型的数据元素的有限序列,线性表中数据元素的个数称为线性表的长度。
线性表是一个相当灵活的数据结构对线性表的数据元素不仅可以进行存取和访问,还可以进行插入和删除操作。
顺序表是用一段地址连续的存储单元依次存储线性表的数据元素。
顺序表的缺点:
单链表(singly linked list)是用一组任意的存储单元存放线性表的元素,这组存储单元可以连续也可以不连续,甚至可以零散的分布在内存中的任意位置。
public class Node {
//节点内容
int data;
//下一个节点
Node next;
public Node(int data) {
this.data = data;
}
//追加节点
public Node append(Node node) {
//当前节点
Node currentNode = this;
//循环找节点
while (true) {
//取出下一个节点
Node nextNode = currentNode.next;
//如果下一个节点为null,表示当前节点为最后一个节点
if (nextNode == null) {
break;
}
//赋值给当前节点
currentNode = nextNode;
}
//把需要追加的节点放在当前节点的下面
currentNode.next = node;
return this;
}
public Node next() {
return next;
}
public int getData() {
return data;
}
}
test
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
node1.append(node2).append(node3);
System.out.println(node1.next().getData());
输出结果:2
有点绕,单链表不能拿到本节点的上一个节点,所以只能删除本节点的下一个节点。
public void removeNext(){
Node newNext = next().next();
this.next = newNext;
}
当然,出入节点的位置在当前节点的下一个节点。
public void insert(Node node){
Node nextNote = next();
this.next = node;
node.next = nextNote;
}
和单链表区别不大,区别就是比单链表多了首尾相连。头尾相接的单链表称为循环单链表,简称循环链表。循环链表中没有明显的尾端,容易进入死循环,需要额外注意循环条件。
public class LoopNode {
//节点内容
int data;
//下一个节点,和单链表差别在这里,没append(Node node) 追加节点这个方法,好好想想为啥
LoopNode next = this;//猪油一个节点的时候,next是他自己
public LoopNode(int data) {
this.data = data;
}
public LoopNode next() {
return next;
}
public int getData() {
return data;
}
public void removeNext() {
LoopNode newNext = next().next();
this.next = newNext;
}
//插入一个节点,
public void insert(LoopNode node) {
LoopNode nextNote = next();
this.next = node;
node.next = nextNote;
}
}
在循环链表中,虽然从人一个节点出发可以扫描到其他节点,单要找到其前驱结点,需要需要遍历整个循环链表。如果需要快速准确定位表中任一节点的前驱结点,可以在单链表的每个节点中在设置一个指向其前驱结点的指针域,这样就形成了双链表(doubly linked list)。
感觉这个不需要写啥了,和循环链表去的区别就是多了一个上一个节点,查找下一个节点,查找上个节点。读者自己类比写吧。懒得写了。
public class DoubleNode {
DoubleNode pre = this;
DoubleNode next = this;
int data;//节点数据
public DoubleNode(int data) {
this.data = data;
}
}
静态链表(static linked list)是用数组来表示单链表,用数组元素的下标来模拟单链表的指针。静态链表的每个数组元素有两部分组成:data域存放数据元素,next域存放该元素的后继元素所在的数组下标。由于它是利用数组定义的,属于静态存储分配,因此叫做静态链表。
时间复杂度
存储密度。
说白了,就是自己调用自己,直到满足一个条件跳出循环。
public static void main(String[] args) {
recursive(20);
}
private static void recursive(int i) {
if (i>0){//满足条件,跳出循环,否则会...你猜?
System.out.println(i);
recursive(--i);//调用自己
}
}
经典的,斐波那契数列。
private static void getFibo(int i) {
for (int j = 1; j <= 20; j++) {
System.out.print(Fibo(j) + "\t");
}
}
private static int Fibo(int i) {
if (i == 1 || i == 2) {
return 1;
} else {
return Fibo(i - 1) + Fibo(i - 2);
}
}
输出
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765