链表
* 链表由节点组成,节点是由next域连接起来的,每个节点=data+next,
* 同时链表在内存中是不连续的。
* 特点:
* 1)访问某个特定的节点,从头开始去找
* 2)删除、添加某一个特定的节点到某一个位置,只需要找到前一个节点,即可直接添加/删除
* 3)链表是一种内存上不连续的数据结构
class SingleLinekdListTakeHead<E> {
protected Node<E> head;//头节点
class Node<E> {
protected E data;//数据域
protected Node<E> next;//next引用域
public Node(E data, Node<E> next) {
this.data = data;
this.next = next;
}
}
//初始化head
public SingleLinekdListTakeHead() {
head = new Node(new Object(), null);
}
//在head之后直接插入一个节点,头插法
public void addHead(E element) {
Node<E> newNode = new Node(element, null);
newNode.next = head.next;//先让新添加的节点的下一个指向原head节点指向的
head.next = newNode;//再让head节点指向新节点
}
//尾插法
public void addTail(E element) {
Node<E> newNode = new Node(element, null);
Node<E> tail = head;//定义一个节点从头走到尾
//tail走到当前链表的尾部
while (tail.next != null) {
tail = tail.next;
}
tail.next = newNode;
newNode.next=null;
}
/**
* 固定位置插入一个节点
* 判断参数合法性
* 找到pos位置的前一个节点
* @param pos 固定位置
* @param element 元素
*/
public void addPos(int pos, E element) {
if (pos <= 0 || pos > getLength()) {
return;
}
Node<E> prev = head.next;
int index = 1;
while (index++ < pos - 1) {
prev = prev.next;
}
Node<E> newNode = new Node<>(element, null);
newNode.next = prev.next;
prev.next = newNode;
}
//删除元素为element的节点
public boolean remove(E element) {
//如果只有一个头结点,返回false
if (head.next == null) {
return false;
}
//找到该元素所对应的节点 + 该元素所对应的节点的前一个
//从头结点开始遍历
Node<E> tmp = head;
while (tmp != null) {
if (tmp.next != null && tmp.next.data == element) {
//tmp.next是我们要删除的节点 tmp是删除节点的前一个
tmp.next = tmp.next.next;
return true;
}
tmp = tmp.next;
}
return false;
}
//设置某个位置的值为newElement
public void set(int pos, E newElement){
if(pos <= 0 || pos > getLength()){
return;
}
//找pos位置的节点
Node<E> tmp = head.next;
for(int i=1; i < pos; i++){
tmp = tmp.next;
}
tmp.data = newElement;
}
//得到某个元素的值
public E get(E element){
Node<E> tmp = head.next;//从有效节点开始遍历
while(tmp != null){
if(tmp.data == element){
return tmp.data; //找到的话,返回该节点
}
tmp = tmp.next;
}
return null;
}
//返回长度
public int getLength() {
Node<E> tmp = head.next;
int length = 0;
while (tmp != null) {
length++;
tmp = tmp.next;
}
return length;
}
//打印栈
public String toString() {
StringBuilder strs = new StringBuilder();
Node<E> tmp = head.next;
while (tmp != null) {
strs.append(tmp.data + " ");
tmp = tmp.next;
}
return strs.toString(); //strs是StringBuilder类型,应该添加toString方法,才能返回String类型的
}
}
public class Linked {
public static void main(String[] args) {
SingleLinekdListTakeHead<Integer> list=new SingleLinekdListTakeHead();
list.addHead(3);
list.addHead(5);
list.addHead(8);
System.out.println(list.toString());//8 5 3
list.addTail(1);
list.addTail(2);
list.addTail(4);
System.out.println(list.toString());//8 5 3 1 2 4
list.addPos(2, 100); //在2 号位置加入元素100
System.out.println(list.toString());
list.addPos(0, 1000);
System.out.println(list.toString());
list.remove(4);
System.out.println("删除值为4的元素:"+list.toString());
list.set(2,2);//true,把2号元素的值改为2
System.out.println("把2号元素的值改为2:"+list.toString());
System.out.println(list.get(3));
}
}