存储结构
顺序存储:地址连续,用数组
链式存储:地址不连续,用指针(引用,面向对象)
链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域(需要用到的实际数据data),另一个是存储下一个结点地址的指针域;即数据域和指针域;而双向链表中,每个结点包括存储其上一个结点地址的指针,用到的数据data和存储下一个结点的指针。数据结构中的每一个数据结点对应于一个存储单元,这种储存单元称为储存结点,也可简称结点。
————————————————
data为实际存放的数据,next为存放下一个结点地址的指针
prev是存放上一个结点地址的指针,data为实际用到的数据,next为存放下一个结点地址的指针
单链表实现代码
public class LinkedList {
private Node first;//定义头节点
private int nItems;//定义单链表中实际的数据的数目
//初始化
public LinkedList() {
this.first = null;
this.nItems = 0;
}
//添加头节点
public void addFirst(int data) {
//新建节点
Node newNode = new Node(data);
//将新节点的下一个节点指向旧的头节点
newNode.next = first;
//将新节点设为头节点
first = newNode;
nItems ++;
}
//删除头结点
public boolean deleteFirst() {
//判断链表是否为空
if(isEmpty()) {
System.out.println("链表为空!");
return false;
}
first = first.next;
nItems --;
return true;
}
//有序链表的插入,这样简单排序就可以用链表来实现,复杂度为O(N)
public void add(int data) {
//创建新节点
Node newNode = new Node(data);
//创建要插入节点之前的节点
Node previous = null;
//创建要插入节点的位置上原来的节点
Node current = first;
//按从小到大的顺序排序
while(current != null && data > current.data) {
previous = current;
current = current.next;
}
if(previous == null) {
first = newNode;
}else {
previous.next = newNode;
}
newNode.next = current;
nItems ++;
}
//查询某个特定值的节点
public Node findNode(int data) {
//定义一个新节点用于查询
Node current = first;
while(current != null && current.data != data) {
if(current.next == null) {
System.out.println("该节点不存在");
return null;
}
current = current.next;
}
return current;
}
//删除某个特定值的节点,并返回该节点
public Node deleteNode(int data) {
//定义被删除节点之前的节点
Node previous = null;
//定义被删除的节点
Node current = first;
while(current != null && current.data != data) {
if(current.next == null) {
System.out.println("该节点不存在");
return null;
}
previous = current;
current = current.next;
}
if(previous == null) {
first = first.next;
}else {
previous.next = current.next;
}
nItems --;
return current;
}
//遍历链表
public void traverseList() {
//定义一个节点用于遍历
Node current = first;
//判断链表是否为空
if(current == null) {
System.out.println("链表为空!");
return;
}
while(current != null) {
System.out.println(current.data);
current = current.next;
}
}
//链表的长度
public int size() {
return nItems;
}
//判断链表是否为空
public boolean isEmpty() {
return first == null;
}
}
//定义节点
class Node{
//声明为public,方便存取
//指向下一个节点
public Node next;
//数据域
public int data;
public Node(int data) {
this.data = data;
}
}
双链表实现代码
public class DoubleLinkedList {
//声明为public,方便存取
//头指针
public Node first;
//尾指针
public Node last;
//链表中实际存储的数据的数目
public int size;
//初始化
public DoubleLinkedList() {
this.first = null;
this.last = null;
this.size = 0;
}
//得到链表容量
public int size() {
return size;
}
//判断链表是否为空
public boolean isEmpty() {
return size == 0;
}
//添加头节点
public void addFirst(int data) {
//创建新节点
Node newNode = new Node(data);
//判断链表是否为空
if(isEmpty()) {
last = newNode;
}else {
first.previous = newNode;
newNode.next = first;
}
first = newNode;
size ++;
}
//添加尾节点
public void addLast(int data) {
//创建新节点
Node newNode = new Node(data);
//判断链表是否为空
if(isEmpty()) {
first = newNode;
}else {
last.next = newNode;
newNode.previous = last;
}
last = newNode;
size ++;
}
//删除头结点,并返回头结点
public Node deleteFirst() {
if(isEmpty()) {
System.out.println("链表为空!");
return null;
}
Node temp = first;
if(size == 1) {
//如果链表中只有一个元素
last = null;
}else {
first.next.previous = null;
}
first = first.next;
size --;
return temp;
}
//删除尾节点,并返回尾节点
public Node deleteLast() {
if(isEmpty()) {
System.out.println("链表为空!");
return null;
}
Node temp = last;
if(size == 1) {
//如果只有一个元素
first = null;
}else {
last.previous.next = null;
}
last = last.previous;
size --;
return temp;
}
//将节点插入到指定值为key的节点后面
public void insert(int key,int value) {
//创建要插入的新节点
Node newNode = new Node(value);
//创建要插入节点位置上原来的节点
Node current = first;
if(isEmpty()) {
System.out.println("没有值为" + key + "的值!");
return;
}
while(current.data != key) {
if(current == null) {
System.out.println("没有值为" + key + "的值!");
return;
}
//往下遍历
current = current.next;
}
current.next.previous = newNode;
newNode.next = current.next;
current.next = newNode;
newNode.previous = current;
size ++;
}
//删除特定的节点,并返回该节点
public Node deleteNode(int value) {
if(isEmpty()) {
System.out.println("没有值为" + value + "的值!");
}
//创建要删除节点
Node current = first;
while(current.data != value) {
if(current == null) {
System.out.println("没有值为" + value + "的值!");
}
//继续向下遍历
current = current.next;
}
//如果要删除的节点为首节点
if(current == first) {
deleteFirst();
}else if(current == last) {
//如果要删除的节点为尾节点
deleteLast();
}else {
current.previous.next = current.next;
current.next.previous = current.previous;
}
size --;
return current;
}
//正向遍历链表
public void traverseForward() {
Node current = first;
while(current != null) {
System.out.println(current.data);
current = current.next;
}
}
//反向遍历链表
public void traverseBackwrad() {
Node current = last;
while(current != null) {
System.out.println(current.data);
current = current.previous;
}
}
}
class Node{
//声明为public,方便存取
//指向前一个节点
public Node previous;
//指向后一个节点
public Node next;
//数据域
public int data;
public Node(int data) {
this.data = data;
}
}
————————————————