1.頭插法 : 該方法從一個空表開始, 不斷創建新節點,將數據元素存入節點的data域中, 然後不斷地以新節點爲頭節點,並讓新節點指向原來的頭節點。
2.尾插法 : 新節點插入當前鏈表的表尾上, 因此需要爲鏈表定義一個引用變量來保存鏈表的最後一個節點。
查找:(1) 找第index個元素:從header節點依次向下在單鏈表中找第index個節點。 算法:以head爲頭, current爲當前節點(初始時current從header起)0 爲頭節點序號, i 爲計數器 則counter依次下移尋找節點, 並使i 同時遞增記錄節點序號, 直到返回指定節點。
(2) 找element元素:找到是否又等於給定element值的節點 有返回相應的索引 ,無返回-1。
插入:element的新節點插入到第index個節點的位置上, 找到index - 1的節點, 生成一個數據域爲element的newNode
使得index -1處的節點的next域指向新的節點, 新節點的next指向原來的index處的節點。
刪除:index個節點刪除, 先找到引用它的index - 1節點, 然後讓index - 1的next指向原來的index + 1節點 ,釋放index處的節點。
參考代碼:
public class LinkList<T> {
//定義一個節點類
private class Node{
//保存數據
private T data;
//下一個節點域
private Node next;
public Node(){
}
public Node(T data, Node next){
this.data = data;
this.next = next;
}
}
//保存頭節點 和 尾節點
private Node header;
private Node tail;//trailer prev域 和 next域 -- 引用域
//鏈表中的節點數
private int size;
//創建空鏈表
public LinkList(){
header = null;
tail = null;
}
//根據指定元素創建鏈表
public LinkList(T element){
header = new Node(element, null);//創建每一個元素是以節點的形式出現的
tail = header;
size ++;
}
//返回鏈表節點的長度
public int length(){
return size;
}
//查找1 回去index處的節點
public T get(int index){
return getNodeByIndex(index).data;
}
//根據索引獲取節點
private Node getNodeByIndex(int index) {
if(index < 0 || index > size -1){
throw new IndexOutOfBoundsException("線性表越界");
}
Node current = header;
for(int i = 0; i < size && current != null; i ++, current = current.next){//依次向下尋找節點
if(i == index){
return current;
}
}
return null;
}
//查找指定的element
public int locate(T element){
Node current = header;
for(int i = 0; i < size && current != null; i ++, current = current.next){//依次向下尋找節點
if(current.data == element){
return i;
}
}
return -1;
}
//插入數據
public void insert(T element, int index){
if(index < 0 || index > size){
throw new IndexOutOfBoundsException("線性表越界");
}
if(header == null){
add(element);
}
else{
if(index == 0){
addAtHeader(element);
}
else{
Node preNode = getNodeByIndex(index - 1);
preNode.next = new Node(element, preNode.next);
size ++;
}
}
}
//頭插法
public void addAtHeader(T element) {
//作爲一個新的頭
header = new Node(element, header);
if(tail == null){
tail = header;
}
size ++;
}
//尾插法
public void add(T element){
//判斷是不是空
if(header == null){
header = new Node(element, null);
tail = header;
}
else{
Node newNode = new Node(element, null);
tail.next = newNode;
tail = newNode;
}
size ++;
}
//刪除數據
public T delete(int index){
if(index < 0 || index > size -1){
throw new IndexOutOfBoundsException("線性表越界");
}
Node delNode = null;
//被刪除的是頭節點
if(index == 0){
header = delNode;
header = header.next;
}
else{
Node preNode = getNodeByIndex(index - 1);
delNode = preNode.next;
preNode = delNode.next;
//被刪除節點的next引用賦值爲null
delNode.next = null;
}
size --;
return delNode.data;
}
//判斷是否爲空
public boolean empty(){
return size == 0;
}
//清空列表
public void clear(){
header = null;
tail = null;
size = 0;
}
public String toString(){
if(size == 0){
return "[]";
}
else{
StringBuffer sb = new StringBuffer("[");
for(Node current = header; current != null; current = current.next){
sb.append(current.data.toString() + ", ");//這裏, 後面的空格很重要, 否則輸出時可能出錯
}
int len = sb.length();
return sb.delete(len - 2, len).append("]").toString();
}
}
}
public static void main(String[] args) {
LinkList<Integer> llist = new LinkList<Integer>();
llist.insert(1, 0);
llist.add(2);//尾插法
llist.add(3);
System.out.println(llist);
System.out.println("2在中的位置:" + llist.locate(2));
llist.addAtHeader(4);
System.out.println(llist);
System.out.println("第2個位置的元素是:" + llist.get(2));
}