链表
链表的概念
链表是一种物理存储结构上非连续存储结构数据元素的逻辑顺序。
与顺序表不同,顺序表是物理结构上连续,逻辑顺序也是连续的,顺序表中间/头部的插入删除,时间复杂度是O(N)。
链表有单向,双向;带头,不带头;循环,非循环之分(具体有单向不带头非循环链表,双向不带头非循环链表;单向不带头循环链表,单向不带头循环链表;单向带头非循环链表,单向带头非循环链表;单向带头循环链表,单向带头循环链表;共8种)。
在带头链表结构中,第一个节点为头结点,第一个data域的值为无效值,这个节点也被称做傀儡节点。
链表的实现
class Node{ //构造节点
public int data;
public Node next;//节点的引用
public Node(int data){//构造方法构造data
this.data = data;
}
}
data域中存的数值不止为int,可以为float,double,等。next域本质为下一节点的引用,所以为节点类型Node,其值在为构建下一节点时是未知的,所以可以先不构建(默认null)。
public class MyLinkedList{
public Node head;//标识单链表的头节点
}
- 头插法
public void addFirst(int data){
Node node = new Node(data);
if(this.head == null){
this.head = node;
}else{
node.next = this.head;//先将head赋给
this.head = node;
}
}
- 尾插法
public void addLast(int data){
Node node = new Node(data);
if(this.head == null){
//第一次插入,使用尾插法
this.head = node;
}else{
Node cur = this.head;
while(cur.next != null){
cur = cur.next;
}
cur.next = node;
}
- 打印
public void display(){
Node cur = this.head;
while(cur != null){
System.out.println(cur.data+",");
}
}
- 任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data){
if(index < 0 || index > getLength()){
System.out.println("下标不合法!");
return;
}
if(index == 0){
addFirst(data);
return;//不能省略
}
if(index == this.getLength()){
addLast(data);
return;
}
Node cur = searchPrev(index);
Node node = new Node(data);
node.next = cur.next;
cur.next = node;
}
//查找前驱(查找index-1的位置,找到返回引用)
public Node searchPrev(int index){
Node cur = this.head;
int count = 0;
while(count < index-1){
cur = cur.next;
count++;
}
return cur;
}
- 单链表长度
public int getLength(){
int count = 0;
Node cur = this.head;
while(cur != null){
count++;
cur = cur.next;
}
return count;
}
- 删除第一次出现关键字为key的节点
public void remove(int key){
if(this.head == null){
return;
}
if(this.head.data == key){
this.head = this.head.next;
return;
}
Node prev = searchPrevNode(key);
if(prev == null){
System.out.println("没有找到要删除的数字");
return;
}
Node del = cur.next;
cur.next = del.next;
}
//实现searchPrevNode函数
public Node searchPrevNode(int key){
Node cur = this.head;
while(cur.next != null){
if(cur.next.data == key){
return cur;
}
cur = cur.next;
}
return null;
}
实现各功能时,采用“高内聚,低耦合”原则:
高内聚指一个模块中各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间的联系程度越高,则内聚性越高。
每个模块之间相互联系的紧密程度,模块之间联系越紧密,则耦合性越高,模块的独立性就越差,不便于调试及维护。
所以应注意将一个整体功能的部分细节处再做细化,化整为零,更加清晰。