單向鍊錶(單鏈表)是鍊錶的一種,其特點是鍊錶的鏈結方向是單向的,對鍊錶的訪問要通過順序讀取從頭部開始。
鏈式儲存結構的線性表將採用一組任意的儲存單元存放線性表中的資料元素。由於不需要按順序儲存,鍊錶在插入、刪除資料元素時比順序儲存要快,但是在查詢乙個節點時則要比順序儲存要慢
使用鏈式儲存可以克服順序線性表需要預先知道資料大小的缺點,鍊錶結構可以充分利用記憶體空間,實現靈活的記憶體動態管理。但是鏈式儲存失去了陣列隨機訪問的特點,同時增加了節點的指標域,空間開銷較大。
下圖就是最簡單最一般的單向鍊錶:
新增節點:
將值為element的新節點插入到第index的位置上。
首先要先找到索引為index-1的節點,然後生成乙個資料為element的新節點newnode,並令index-1處節點的next指向新節點,新節點的next指向原來index處的節點。
刪除節點:
刪除第index個節點,第index節點是由index-1出的節點引用的,因此刪除index的節點要先獲取index-1處的節點,然後讓index-1出節點的next引用到原index+1處的節點,並釋放index處節點即可。
下面的程式分別實現了線性表的初始化、獲取線性表長度、獲取指定索引處元素、根據值查詢、插入、刪除、清空等操作。
public class linklist
// 初始化全部屬性的構造器
public node(t data, node next)
} private node header;// 儲存頭結點
private node tail;// 儲存尾節點
private int size;// 儲存已含有的節點數
// 建立空鍊錶
public linklist
()
// 已指定資料元素建立鍊錶,只有乙個元素
public linklist(t element)
// 返回鍊錶的長度
public int length
()
// 獲取指定索引處的元素
public t get(int index)
//獲取指定位置的節點
private node getnodebyindex(int index)
node current = header;//從header開始遍歷
for(int i=0; iif(i == index)
} return null;
} //按值查詢所在位置
public int locate(t element)
} return -1;
} //指定位置插入元素
public void insert(t element, int index)
//如果是空鍊錶
if(header == null)
else
else
} }
//在尾部插入元素
public void add(t element)
else
size++;
} //頭部插入
public void addathead(t element)
size++;
} //刪除指定索引處的元素
public t delete(int index)
node del = null;
//若要刪除的是頭節點
if(index == 0)
else
size--;
return del.data;
} //刪除最後乙個元素
public t remove
()
//判斷線性表是否為空
public boolean isempty
()
//清空線性表
public void clear
()
public string tostring
()
else
int len = sb.length();
} }
} 複製**
import org.junit.test;
import com.sihai.algorithm.linklist;
public class linklisttest
} 複製**
1. 鍊錶反轉/**
* 鍊錶反轉
* * @param head
* @return
*/public node reverseiteratively(node head)
pnode.next = pprev;
pprev = pnode;
pnode = pnext;
}this.head = preversedhead;
return this.head;
}複製**
2. 查詢單鏈表的中間節點
採用快慢指標的方式查詢單鏈表的中間節點,快指標一次走兩步,慢指標一次走一步,當快指標走完時,慢指標剛好到達中間節點。
/**
* 查詢單鏈表的中間節點
* * @param head
* @return
*/public node searchmid(node head)
system.out.println("mid:" + q.data);
return q;
}複製**
3. 查詢倒數第k個元素
採用兩個指標p1,p2,p1先前移k步,然後p1、p2同時移動,當p1移動到尾部時,p2所指位置的元素即倒數第k個元素 。
/**
* 查詢倒數 第k個元素
* * @param head
* @param k
* @return
*/public node findelem(node head, int k)
node p1 = head;
node p2 = head;
for (int i = 0; i < k; i++)// 前移k步
p1 = p1.next;
while (p1 != null)
return p2;
}複製**
4. 對鍊錶進行排序/**
* 排序
* * @return
*/public node orderlist
() nextnode = nextnode.next;
}curnode = curnode.next;
}return head;
}複製**
5. 刪除鍊錶中的重複節點/**
* 刪除重複節點
*/public void deleteduplecate(node head) else
q = q.next;
}p = p.next;}}
複製**
6. 從尾到頭輸出單鏈表,採用遞迴方式實現/**
* 從尾到頭輸出單鏈表,採用遞迴方式實現
* * @param plisthead
*/public void printlistreversely(node plisthead)
}複製**
7. 判斷鍊錶是否有環,有環情況下找出環的入口節點/**
* 判斷鍊錶是否有環,單向鍊錶有環時,尾節點相同
* * @param head
* @return
*/public boolean isloop(node head)
while (fast != null && fast.next != null)
}return !(fast == null || fast.next == null);
}/**
* 找出鍊錶環的入口
* * @param head
* @return
*/public node findloopport(node head)
if (fast == null || fast.next == null)
return null;
slow = head;
while (slow != fast)
return slow;
}複製**
自己動手寫乙個單鏈表
單向鍊錶 單鏈表 是鍊錶的一種,其特點是鍊錶的鏈結方向是單向的,對鍊錶的訪問要通過順序讀取從頭部開始。鏈式儲存結構的線性表將採用一組任意的儲存單元存放線性表中的資料元素。由於不需要按順序儲存,鍊錶在插入 刪除資料元素時比順序儲存要快,但是在查詢乙個節點時則要比順序儲存要慢 使用鏈式儲存可以克服順序線...
自己動手寫乙個單鏈表
單向鍊錶 單鏈表 是鍊錶的一種,其特點是鍊錶的鏈結方向是單向的,對鍊錶的訪問要通過順序讀取從頭部開始。鏈式儲存結構的線性表將採用一組任意的儲存單元存放線性表中的資料元素。由於不需要按順序儲存,鍊錶在插入 刪除資料元素時比順序儲存要快,但是在查詢乙個節點時則要比順序儲存要慢 使用鏈式儲存可以克服順序線...
自己動手寫乙個APK安裝器 一
一 安裝器的功能 1.安裝程式功能 2.解除安裝程式功能。二 技術要點 1.掃瞄sd卡和rom上的所有apk檔案 2.用 解析apk檔案,獲取apk檔案的icon label和packagename 3.呼叫系統的安裝程式進行安裝 4.獲得所有使用者已經安裝的程式列表 5.呼叫系統的解除安裝程式進行...