1、前言
數據結構,是計算機編程中對數據存儲最基本的操作,不同的數據結構適用不同的業務場景。如今大部分情況都是調用開發API封裝好的類庫,直接調用,幾乎不需要程序員再去深究其中背後實現的邏輯,大大簡化和減低了對程序員的要求。正是這種,知其然而不知其所以然,導致很多程序員缺乏對於底層結構的瞭解,分不清楚不同數據結構之間的性能差異,導致出現很多系統性能問題。
2、原理推導
鏈表的運用,鏈表是一種特殊的線性表,由一系列的節點組成,節點在鏈表中的順序由節點元素中包含的對象鏈接順序確定位置。鏈表中的節點一部分是自身的數據,另一部分爲節點指向的下一個節點的引用。
示例中,第一個節點【9】包含指向下一個節點【5】的指針,自身的數據+指針,這樣構成了一個單向鏈表中的節點。單向鏈表在表頭插入和刪除操作效率很高,對於鏈表來說就是修改指針的引用,時間複雜度爲常量O(1)。查找功能時間複雜度爲O(N),比數組要快,鏈表操作不需要移動和複製數據。
3、代碼示例
# 鏈表數據封裝
/**
* 鏈表的數據封裝
*/
public class LinkNodeFlat {
private int id;
private LinkNodeFlat nodeFlat;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public LinkNodeFlat getNodeFlat() {
return nodeFlat;
}
public void setNodeFlat(LinkNodeFlat nodeFlat) {
this.nodeFlat = nodeFlat;
}
public LinkNodeFlat(int id) {
super();
this.id = id;
}
public void printLink(){
StringBuffer str = new StringBuffer();
str.append("id="+id);
if (nodeFlat != null){
str.append(" , nextNode=").append(nodeFlat.getId());
}
System.out.println(str);
}
}
# 利用單向鏈表完成節點增刪改查
/**
* 鏈表的基本實現
*/
public class SingleLinkList {
private LinkNodeFlat firstNode;
/**
* 添加鏈表節點元素
* @param id
*/
public void insertFirst(int id){
//存放節點本身的數據
LinkNodeFlat newLinkNode = new LinkNodeFlat(id);
// 存放下一個節點的對象引用
newLinkNode.setNodeFlat(firstNode);
firstNode = newLinkNode;
}
/**
* 移除鏈表中第一個節點
* @return
*/
public LinkNodeFlat removeFirst(){
LinkNodeFlat temp = firstNode;
// 移除第一節點,第一個節點後的節點成爲新的第一節點
firstNode = firstNode.getNodeFlat();
return temp;
}
/**
* 查找指定節點
* @param id
* @return
*/
public LinkNodeFlat find(int id){
LinkNodeFlat node = firstNode;
//從第一個節點向下查找
while(node.getId()!=id){
if(node.getNodeFlat() == null){
return null;
}else{
// 獲取鏈表下一個節點對象
node = node.getNodeFlat();
}
}
return node;
}
/**
* 移除指定的節點
* @param id
* @return
*/
public LinkNodeFlat remove(int id){
LinkNodeFlat currentNode = firstNode;
LinkNodeFlat previousNode = firstNode;
//從第一個節點向下查找需要刪除的結點
while(currentNode.getId() != id){
if(currentNode.getNodeFlat() == null){
return null;
}else{
//如果ID不相等,當前節點更新爲下一個待比較節點的前驅節點
previousNode = currentNode;
//當前節點的下一個節點變成下一個待比較的節點
currentNode = currentNode.getNodeFlat();
}
}
// 如果移除的節點就是第一個節點,則第一節點後的節點成爲新的第一節點
if(currentNode.equals(firstNode)){
firstNode = firstNode.getNodeFlat();
}else{
// 前驅節點的下一個節點,設置爲被刪除節點的下一個節點
previousNode.setNodeFlat(currentNode.getNodeFlat());
}
return currentNode;
}
/**
* 打印鏈表節點數據
*/
public void printNodeList(){
System.out.println("-----思維的持續-----");
LinkNodeFlat tempNode = firstNode;
while(tempNode!=null){
tempNode.printLink();
// 獲取鏈表下一個節點對象
tempNode = tempNode.getNodeFlat();
}
}
public static void main(String[] args) {
SingleLinkList linkList = new SingleLinkList();
linkList.insertFirst(7);
linkList.insertFirst(2);
linkList.insertFirst(5);
linkList.insertFirst(9);
linkList.printNodeList();
linkList.removeFirst();
linkList.printNodeList();
LinkNodeFlat result = linkList.find(5);
System.out.println("result:");
result.printLink();
linkList.printNodeList();
linkList.remove(5);
linkList.printNodeList();
}
}
4、禪定時刻
單向鏈表在表頭插入和刪除操作效率很高,對於鏈表來說就是修改指針的引用,時間複雜度爲常量O(1)。查找功能時間複雜度爲O(N),比數組要快,鏈表操作不需要移動和複製數據。
作者簡介
思維的持續,一個真的有思想,不穿格子襯衫的程序員。