單向鏈表是一種線性表,實際上是由節點(Node)組成的,一個鏈表擁有不定數量的節點。其數據在內存中存儲是不連續的,它存儲的數據分散在內存中,每個結點只能也只有它能知道下一個結點的存儲位置。由N各節點(Node)組成單向鏈表,每一個Node記錄本Node的數據及下一個Node。向外暴露的只有一個頭節點(Head),我們對鏈表的所有操作,都是直接或者間接地通過其頭節點來進行的。
Java代碼1
import lianbiao.MyLink.Node;
public class SingleList {
// 由於類中的靜態方法不能直接調用動態方法,所以將Node內部類修飾爲靜態類
public static class Node{
public int data;
public Node next;
public Node(){}
public Node(int data){
this.data = data;
this.next = null;
}
public int getData() {
return this.data;
}
public void setData(int data) {
this.data = data;
}
public Node getNext() {
return this.next;
}
public void setNext(Node next) {
this.next = next;
}
}
//對頭結點的初始化,如果不初始化,將會空指針異常,無法進行以下Node temp=head; temp.next的操作
public Node head = new Node(2);
//count用來統計鏈表的長度
public int count;
public SingleList(){}
/**
* 統計鏈表中結點的個數
* @return
*/
public int size(){
return this.count;
}
/**
* 判斷鏈表是否爲空
* @return
*/
public boolean isEmpty(){
return this.head == null ? true : false;
}
/**
* 增加一個結點
* @param node
* 在鏈表的最後插入新的結點
* 將原本最後一個結點的next指向新結點
*/
public void addNode(Node node){
//一個移動的指針(把頭結點看做一個指向結點的指針)
Node temp=head;
//遍歷單鏈表,直到遍歷到最後一個則跳出循環
while(temp.next != null){
//往後移一個結點,指向下一個結點。
temp=temp.next;
}
//temp爲最後一個結點,將其next指向新結點
temp.next=node;
//統計結點的個數
count++;
}
/**
* 在指定位置插入結點
* @param index
* @param node
*/
public void insertNodeByIndex(int index,Node node){
if(index<1 || index>this.count){
System.out.println(count);
System.out.println("插入的位置不合理");
return ;
}
//記錄我們遍歷到第幾個結點了,也就是記錄位置。
int length = 1;
//可移動的指針
//我們的temp代表的是當前位置的前一個結點。
//前一個結點 當前位置 後一個結點
//temp temp.next temp.next.next
Node temp = head;
//遍歷單鏈表
while(head.next != null){
//判斷是否到達指定位置
if(index == length){
//結點插入操作
node.next = temp.next;
temp.next = node;
count++;
return;
}
length++;
temp = temp.next;
}
}
/**
* 刪除某個位置的結點
* @param index
*/
public void deleteNodeByIndex(int index){
if(index<1 || index>=this.count){
System.out.println("給定的位置不合理");
return ;
}
int length=1;
Node temp = head;
while(temp.next != null){
if(index == length){
//結點刪除操作
temp.next = temp.next.next;
count--;
return;
}
length++;
temp = temp.next;
}
}
/**
* 某個數據是否在鏈表中
* @param data
* @return
*/
public boolean isContain(int data){
//flag爲函數標記,用來表示函數執行的結果
boolean flag=false;
//temp爲頭結點 tail爲頭結點的下一個結點
Node temp=head;
Node tail=head.next;
if(temp == null){
System.out.println("該鏈表是空鏈表!");
flag = false;
}
else{
while(tail != null){
if(tail.data==data){
flag = true;
break;
}
temp = tail;
tail = tail.next;
}
}
return flag;
}
public void print(){
Node temp=head.next;
System.out.print("鏈表遍歷結果爲: ");
while(temp != null){
System.out.print(temp.data+" ");
temp = temp.next;
}
System.out.println();
}
public static void main(String[] args) {
SingleList list = new SingleList();
/*SingleList.Node nodes = new Node(7)是對鏈表頭結點的初始化操作
初始化值的大小不影響最終的函數運行結果
如果不進行初始化操作,nodes爲null,無法調用鏈表的長度,添加結點等函數操作*/
SingleList.Node nodes = new Node(7);
System.out.println(list.isEmpty());
System.out.println("鏈表的長度爲:"+list.size());
System.out.println("==================");
SingleList.Node nodes1 = new Node(2);
SingleList.Node nodes2 = new Node(2);
SingleList.Node nodes3 = new Node(6);
list.addNode(nodes);
list.insertNodeByIndex(1, nodes1);
list.insertNodeByIndex(5, nodes2);
System.out.println(list.isEmpty());
System.out.println("鏈表的長度爲:"+list.size());
System.out.println("==================");
list.addNode(nodes3);
System.out.println(list.isEmpty());
System.out.println("鏈表的長度爲:"+list.size());
System.out.println("==================");
list.deleteNodeByIndex(4);
System.out.println(list.isEmpty());
System.out.println("鏈表的長度爲:"+list.size());
System.out.println("==================");
list.print();
System.out.println("鏈表中是否存在2這個元素:"+list.isContain(2));
System.out.println("鏈表中是否存在5這個元素:"+list.isContain(5));
System.out.println("鏈表中是否存在6這個元素:"+list.isContain(6));
}
}
程序運行結果:
false
鏈表的長度爲:0
==================
2
插入的位置不合理
false
鏈表的長度爲:2
==================
false
鏈表的長度爲:3
==================
給定的位置不合理
false
鏈表的長度爲:3
==================
鏈表遍歷結果爲: 2 7 6
鏈表中是否存在2這個元素:true
鏈表中是否存在5這個元素:false
鏈表中是否存在6這個元素:true
Java代碼2
import lianbiao.SingleList.Node;
public class MyLink {
//定義鏈表頭結點
Node head = null;
static class Node {
// 節點的引用,指向下一個節點
Node next = null;
// 節點的對象,即數據域
int data;
Node(){}
public Node(int data) {
this.data = data;
}
}
/**
* 增加一個結點
* @param d
*/
public void addNode(int d) {
// 實例化一個節點
Node newNode = new Node(d);
if (head == null) {
head = newNode;
return;
}
//一個移動的指針(把頭結點看做一個指向結點的指針)
Node tmp = head;
while (tmp.next != null) {
tmp = tmp.next;
}
//temp爲最後一個結點,將其next指向新結點
tmp.next = newNode;
}
public void insertNodeByIndex(int index,Node node){
if (index < 1 || index > length()) {
System.out.println("插入的位置不合理");
return ;
}
int i=1;
Node preNode = head;
Node curNode = preNode.next;
//遍歷單鏈表
while(curNode != null){
//判斷是否到達指定位置
if(i == index){
//結點插入操作
node.next = curNode;
preNode.next = node;
return;
}
preNode = curNode;
curNode = curNode.next;
i++;
}
}
/**
* @param index:刪除第index個節點
* @return
*/
public boolean deleteNode(int index) {
if (index < 1 || index > length()) {
return false;
}
if (index == 1) {
head = head.next;
return true;
}
//i表示第i個位置
int i = 1;
Node preNode = head;
Node curNode = preNode.next;
//循環遍歷尋找第i個結點的位置
while (curNode != null) {
if (i == index) {
preNode.next = curNode.next;
return true;
}
preNode = curNode;
curNode = curNode.next;
i++;
}
return false;
}
/**
* 鏈表長度
* @return 返回節點長度
*/
public int length() {
int length = 0;
Node tmp = head;
while (tmp != null) {
length++;
tmp = tmp.next;
}
return length;
}
/**
* 某個數據是否在鏈表中
* @param data
* @return
*/
public boolean isContain(int data){
//flag爲函數標記,用來表示函數執行的結果
boolean flag=false;
//temp爲頭結點 tail爲頭結點的下一個結點
Node temp=head;
Node tail=head.next;
if(temp == null){
System.out.println("該鏈表是空鏈表!");
flag = false;
}
else{
while(tail != null){
if(tail.data==data){
flag = true;
break;
}
temp = tail;
tail = tail.next;
}
}
return flag;
}
/**
* 打印鏈表
*/
public void printList() {
Node tmp = head;
while (tmp != null) {
System.out.print(tmp.data+" ");
tmp = tmp.next;
}
System.out.println();
}
public static void main(String[] args) {
MyLink list = new MyLink();
System.out.println("鏈表的長度爲:" + list.length());
System.out.println("================");
list.addNode(5);
list.addNode(3);
list.addNode(1);
list.addNode(2);
list.addNode(55);
list.addNode(36);
System.out.println("鏈表的長度爲:" + list.length());
System.out.println("頭結點的數據域爲:" + list.head.data);
System.out.print("鏈表打印結果爲:");
list.printList();
System.out.println("================");
list.deleteNode(4);
System.out.print("After deleteNode(4):");
System.out.print("鏈表打印結果爲:");
list.printList();
System.out.println("================");
//如果不使用list.insertNodeByIndex(3, new Node(25))代碼,Node內部類將不用定義爲靜態內部類
list.insertNodeByIndex(3, new Node(25));
System.out.println("鏈表的長度爲:" +list.length());
System.out.print("鏈表打印結果爲:");
list.printList();
System.out.println("================");
System.out.println("鏈表是否包含數據域爲25的結點:"+list.isContain(25));
System.out.println("鏈表是否包含數據域爲10的結點:"+list.isContain(10));
}
}
程序運行結果:
鏈表的長度爲:0
================
鏈表的長度爲:6
頭結點的數據域爲:5
鏈表打印結果爲:5 3 1 2 55 36
================
After deleteNode(4):鏈表打印結果爲:5 3 1 2 36
================
鏈表的長度爲:6
鏈表打印結果爲:5 3 1 25 2 36
================
鏈表是否包含數據域爲25的結點:true
鏈表是否包含數據域爲10的結點:false