什么是链表?
链表是一个线性结构,但是存储的数据可以是非线性的。链表由一个个子节点构成,每个节点有两个部分:数据域和指针域,数据域就是实际存储数据的,指针域可以有一个和两个,单链表就是单个指针域指向后一个节点,双链表就是节点有两个指针域,分别指向前一个和后一个节点。
链表的核心:
链表的核心就是指针域,通过对指针域的操作实现增加节点删除节点,所谓链表就是形象的表示出一环扣一环,这是链表的优点也是缺点,优点是:插入删除不需要移动所有节点,只需要将待插入的节点的指针域一个指向待插入位置的后一个节点,一个指向前一个节点;缺点就是搜索的时候必须遍历节点。
Java实现链表基本操作
//一个节点
class Node {
public Node next;
public Node prev;
public E item;
public Node(E data) {
this.item = data;
next = null;
prev = null;
}
}
public class MyLinkedList {
private Node head; //表头
private Node tail; //表尾
private int size; //表长
public MyLinkedList() {
size = 0;
head = null;
tail = null;
}
public int size() {
return this.size;
}
public void add(E o) { //将o增加到链表尾部
Node tempNode = new Node(o);
if(size == 0){ //节点为空节点的时候
head = tempNode;
tail =tempNode;
}else {
tail.next = tempNode;
tempNode.prev = tail;
tail = tempNode;
}
size++;
}
public E remove() { //从头移除元素
return removeFirst();
}
public void showList(){
Node tempNode = head;
while(tempNode != null){
System.out.println(tempNode.item + " ");
tempNode = tempNode.next;
}
}
public void showListRevise(){
Node tempNode = tail;
while(tempNode != null){
System.out.println(tempNode.item + " ");
tempNode = tempNode.prev;
}
}
public E remove(int index) { //删除指定位置的元素
Node tempNode;
Node resultNode;
if(index<0 || index>size){
return null;
}else {
if (index < (size >> 1)) {
tempNode = head;
for(int i=0;i
tempNode = tempNode.next;
Node par = tempNode.prev;
Node ch = tempNode.next;
tempNode.prev.next = tempNode.next;
tempNode.next.prev = tempNode.prev;
resultNode = tempNode;
} else {
tempNode = tail;
for(int i=size-1;index
tempNode = tempNode.prev;
resultNode = tempNode;
tempNode = tempNode.prev;
}
size--;
return resultNode.item;
}
}
public boolean remove(Object o) {
return removeFirstOccurrence(0);
}
public E removeFirst() {
Node tempNode;
if(size>0){
tempNode = head;
head = head.next;
head.prev = null;
size--;
return tempNode.item;
}else
return null;
}
public E removeLast() {
E temp = tail.item;
tail = tail.prev;
tail.next = null;
size--;
return temp;
}
public boolean removeFirstOccurrence(Object o){ //删除此列表中指定元素的第一个出现(从头到尾遍历列表时)。
int tempSize = size;
Node tempNode = head;
for(int i=0;i
if(tempNode.item.equals(o)){
tempNode.prev = tempNode.next;
tempNode.next = tempNode.prev;
size--;
return true;
}
}
return false;
}
public void addFirst(E o) { //将o插入链表开头
Node tempNode = new Node(o);
if(size==0){
head = tempNode;
tail = tempNode;
}else {
tempNode.next = head;
tempNode.prev = null; //前一个节点是空
head = tempNode;
}
size++;
}
public void addLast(E o) { //将o增加到链表尾部
Node tempNode = new Node(o);
if(size==0){
head = tempNode;
tail = tempNode;
}else {
tail.next = tempNode;
tempNode.prev = tail;
tail = tempNode;
}
size++;
}
public void clear() { //清空链表
head = null;
tail = null;
size = 0;
}
public boolean contains(E o) { //判断元素o是否包含于链表
int tempSize = size;
Node tempNode = head;
Boolean result = false;
while (tempSize != 0) {
Object o1 = tempNode.item;
if(o.equals(o1)){
result = true;
}
tempNode = tempNode.next;
tempSize--;
}
return result;
}
public E get(int index) { //获取指定节点
Node tempNode;
if(index < 0 || index >= size) {
return null;
}else {
if(index < (size >> 1)) { //右移
tempNode = head;
for(int i=0;i
tempNode = tempNode.next;
return tempNode.item;
}else {
tempNode = tail;
for (int i = size-1; index < i; i--) {
System.out.println(index+ " " + i);
tempNode = tempNode.prev;
}
return tempNode.item;
}
}
}
}