链表
* 链表由节点组成,节点是由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)); } }