一、链表相关概念
1. 线性表、数组和链表
- 线性表
- 又称顺序表。线性表中的每一个数据称为一个元素,每个元素有且只有一个前驱元素。除了最后一个元素,每个元素有且仅有一个直接后继元素。
- 数据元素之间的关系是一对一的关系。
- 数组
- 线性表的一种顺序存储方式。数组的内存是连续分配的,并且是静态分配的,即在使用数组之前需要分配固定大小的空间。
- 可以通过索引直接得到数组中的元素,获取数组中元素的时间复杂度为O(1)
- 链表
- 线性表的一种链式存储结构。链表的内存不连续分配,并且是动态分配。
- 链表通过一个指向下一个元素地址的引用将链表中的元素串起来。
2. 链表的分类
二、单向链表
1. 单向链表的组成
- 单链表中的元素由数据域和Next指针域组成,各元素通过Next指针域连接。
- 每个元素都存在后继元素(链尾除外)
2. 单向链表的插入
3. 单向链表的删除
4. 单线链表的实现
public class SingleLinkedList {
public SingleNode head;
public int length;
SingleLinkedList() {
this.head = new SingleNode(null);
}
public boolean isEmpty() {
return length == 0;
}
public int length() {
return length;
}
public boolean add(int value) {
SingleNode node = new SingleNode(value);
SingleNode temp = head;
while (null != temp.next) {
temp = temp.next;
}
temp.next = node;
length++;
return true;
}
public boolean addAt(int i, int value) {
if (length < i){
return false;
}
SingleNode node = new SingleNode(value);
SingleNode temp = head;
for (int k = 0; k < i - 1; k++) {
temp = temp.next;
}
node.next = temp.next;
temp.next = node;
length++;
return true;
}
public boolean removeAt(int i) {
if (length < i){
return false;
}
SingleNode temp = head;
for (int k = 0; k < i - 1; k++){
temp = temp.next;
}
temp.next = temp.next.next;
length--;
return true;
}
public boolean remove(int value) {
SingleNode temp = head;
while (null != temp.next){
if (temp.next.value.equals(value)){
temp.next = temp.next.next;
length--;
return true;
}
temp = temp.next;
}
return false;
}
public SingleNode find(int i){
if (i > length){
return null;
}
SingleNode temp = head;
for (int k = 0; k < i; k++){
temp = temp.next;
}
return temp;
}
public boolean update(int i, int value){
if (i > length){
return false;
}
SingleNode temp = head;
for (int k = 0; k < i; k++){
temp = temp.next;
}
temp.value = value;
return true;
}
public void print(){
SingleNode temp = head;
while (null != temp.next){
temp = temp.next;
System.out.println(temp.value);
}
}
public static class SingleNode {
Integer value;
SingleNode next;
SingleNode(Integer value){
this.value = value;
}
}
public static void main(String[] args){
SingleLinkedList list = new SingleLinkedList();
list.add(3);
list.add(2);
list.add(4);
list.addAt(3, 5);
list.remove(7);
list.removeAt(5);
list.remove(3);
list.removeAt(1);
SingleNode singleNode = list.find(1);
list.update(2, 6);
list.print();
}
}
三、双向链表
1. 双向链表的组成
- 双链表的元素由数据域、Prev指针域和Next指针域组成,各元素通过Prev指针域和Next指针域链接。
- 每个元素都存在前驱元素和后继元素(链头没有前驱,链尾没有后继)
2. 双向链表的插入
3. 双向链表的删除
4. 双向链表的实现
public class DoubleLinkedList {
public DoubleNode head;
public int length;
DoubleLinkedList() {
this.head = new DoubleNode(null);
}
public boolean isEmpty() {
return length == 0;
}
public int length() {
return length;
}
public boolean add(int value) {
DoubleNode node = new DoubleNode(value);
DoubleNode temp = head;
while (null != temp.next) {
temp = temp.next;
}
temp.next = node;
node.pre = temp;
length++;
return true;
}
public boolean addAt(int i, int value) {
if (i > length){
return false;
}
DoubleNode node = new DoubleNode(value);
DoubleNode temp = head;
for (int k = 0; k < i - 1; k++){
temp = temp.next;
}
node.next = temp.next;
temp.next.pre = node;
node.pre = temp;
temp.next = node;
length++;
return true;
}
public boolean removeAt(int i){
if (i > length){
return false;
}
DoubleNode temp = head;
for (int k = 0; k < i; k++){
temp = temp.next;
}
temp.pre.next = temp.next;
temp.next.pre = temp.pre;
length--;
return true;
}
public boolean remove(int value){
DoubleNode temp = head;
while (null != temp.next){
temp = temp.next;
if (temp.value == value){
temp.pre.next = temp.next;
temp.next.pre = temp.pre;
length--;
return true;
}
}
return false;
}
public DoubleNode find(int i){
if (i > length){
return null;
}
DoubleNode temp = head;
for (int k = 0; k < i; k++){
temp = temp.next;
}
return temp;
}
public boolean update(int i, int value){
if (i > length){
return false;
}
DoubleNode temp = head;
for (int k = 0; k < i; k++){
temp = temp.next;
}
temp.value = value;
return true;
}
public void print(){
DoubleNode temp = head;
while (null != temp.next){
temp = temp.next;
System.out.println(temp.value);
}
}
public static class DoubleNode {
Integer value;
DoubleNode pre;
DoubleNode next;
DoubleNode(Integer value){
this.value = value;
}
}
public static void main(String[] args){
DoubleLinkedList list = new DoubleLinkedList();
list.add(3);
list.add(2);
list.add(4);
list.addAt(3, 5);
list.remove(7);
list.removeAt(5);
list.remove(3);
list.removeAt(1);
DoubleNode singleNode = list.find(1);
list.update(2, 6);
list.print();
}
}
四、单向循环链表
1. 单向循环链表的组成
- 单链表中的元素由数据域和Next指针域组成,各元素通过Next指针域连接。
- 每个元素都存在后继元素(包括链尾)
2. 单向循环链表的插入
3. 单向循环链表的删除
4. 单向循环链表的实现
public class SingleCycleLinkedList {
public SingleCyleNode head;
public SingleCyleNode tail;
public int length;
SingleCycleLinkedList(){
this.head = new SingleCyleNode(null);
this.tail = new SingleCyleNode(null);
head.next = tail;
tail.next = head;
}
public boolean isEmpty(){
return length == 0;
}
public int length(){
return length;
}
public boolean add(int value) {
SingleCyleNode node = new SingleCyleNode(value);
SingleCyleNode temp = head;
while (tail != temp.next) {
temp = temp.next;
}
temp.next = node;
node.next = tail;
length++;
return true;
}
public boolean addAt(int i, int value) {
if (length < i){
return false;
}
SingleCyleNode node = new SingleCyleNode(value);
SingleCyleNode temp = head;
for (int k = 0; k < i - 1; k++) {
temp = temp.next;
}
node.next = temp.next;
temp.next = node;
length++;
return true;
}
public boolean removeAt(int i) {
if (length < i){
return false;
}
SingleCyleNode temp = head;
for (int k = 0; k < i - 1; k++){
temp = temp.next;
}
temp.next = temp.next.next;
length--;
return true;
}
public boolean remove(int value) {
SingleCyleNode temp = head;
while (tail != temp.next){
if (temp.next.value == value){
temp.next = temp.next.next;
length--;
return true;
}
temp = temp.next;
}
return false;
}
public SingleCyleNode find(int i){
if (i > length){
return null;
}
SingleCyleNode temp = head;
for (int k = 0; k < i; k++){
temp = temp.next;
}
return temp;
}
public boolean update(int i, int value){
if (i > length){
return false;
}
SingleCyleNode temp = head;
for (int k = 0; k < i; k++){
temp = temp.next;
}
temp.value = value;
return true;
}
public void print(){
SingleCyleNode temp = head;
while (tail != temp.next){
temp = temp.next;
System.out.println(temp.value);
}
}
public static class SingleCyleNode {
Integer value;
SingleCyleNode next;
SingleCyleNode(Integer value){
this.value = value;
}
}
public static void main(String[] args){
SingleCycleLinkedList list = new SingleCycleLinkedList();
list.add(3);
list.add(2);
list.add(4);
list.addAt(3, 5);
list.remove(7);
list.removeAt(5);
list.remove(3);
list.removeAt(1);
SingleCyleNode singleNode = list.find(1);
list.update(2, 6);
list.print();
}
}
五、双向循环链表
1. 双向循环链表的组成
- 双链表的元素由数据域、Prev指针域和Next指针域组成,各元素通过Prev指针域和Next指针域链接。
- 每个元素都存在前驱元素和后继元素(包括链头和链尾)
2. 双向循环链表的插入
3. 双向循环链表的删除
4. 双向循环链表的实现
public class DoubleCycleLinkedList {
public DoubleCycleNode head;
public DoubleCycleNode tail;
public int length;
DoubleCycleLinkedList(){
this.head = new DoubleCycleNode(null);
this.tail = new DoubleCycleNode(null);
head.next = tail;
head.pre = tail;
tail.next = head;
tail.pre = head;
}
public boolean add(int value) {
DoubleCycleNode node = new DoubleCycleNode(value);
DoubleCycleNode temp = head;
while (tail != temp.next) {
temp = temp.next;
}
temp.next = node;
node.pre = temp;
tail.pre = node;
node.next = tail;
length++;
return true;
}
public boolean addAt(int i, int value) {
if (length < i){
return false;
}
DoubleCycleNode node = new DoubleCycleNode(value);
DoubleCycleNode temp = head;
for (int k = 0; k < i - 1; k++) {
temp = temp.next;
}
node.next = temp.next;
temp.next = node;
length++;
return true;
}
public boolean removeAt(int i) {
if (length < i){
return false;
}
DoubleCycleNode temp = head;
for (int k = 0; k < i - 1; k++){
temp = temp.next;
}
temp.next = temp.next.next;
length--;
return true;
}
public boolean remove(int value) {
DoubleCycleNode temp = head;
while (tail != temp.next){
if (temp.next.value == value){
temp.next = temp.next.next;
length--;
return true;
}
temp = temp.next;
}
return false;
}
public DoubleCycleNode find(int i){
if (i > length){
return null;
}
DoubleCycleNode temp = head;
for (int k = 0; k < i; k++){
temp = temp.next;
}
return temp;
}
public boolean update(int i, int value){
if (i > length){
return false;
}
DoubleCycleNode temp = head;
for (int k = 0; k < i; k++){
temp = temp.next;
}
temp.value = value;
return true;
}
public void print(){
DoubleCycleNode temp = head;
while (tail != temp.next){
temp = temp.next;
System.out.println(temp.value);
}
}
public static class DoubleCycleNode{
Integer value;
DoubleCycleNode pre;
DoubleCycleNode next;
DoubleCycleNode(Integer value){
this.value = value;
}
}
public static void main(String[] args){
DoubleCycleLinkedList list = new DoubleCycleLinkedList();
list.add(3);
list.add(2);
list.add(4);
list.addAt(3, 5);
list.remove(7);
list.removeAt(5);
list.remove(3);
list.removeAt(1);
DoubleCycleNode singleNode = list.find(1);
list.update(2, 6);
list.print();
}
}