更新時間:2018年12月07日11時28分 來源:傳智播客 瀏覽次數(shù):
# 數(shù)據(jù)結(jié)構(gòu)-單鏈表的數(shù)據(jù)操作及特性
## 概述
? 上一章中,我們已經(jīng)入門了單鏈表的添加數(shù)據(jù)以及查詢數(shù)據(jù)打印了,那么當我們存儲了數(shù)據(jù),要刪除的時候怎么辦呢?這章,我們來看看如何刪除數(shù)據(jù)。
![](image\image1.png)
## 根據(jù)數(shù)據(jù)刪除節(jié)點
### 分析
? 根據(jù)數(shù)據(jù)刪除節(jié)點,
1. 首先:刪除數(shù)據(jù)分三種情況,1.刪除的節(jié)點是頭節(jié)點 2.刪除的節(jié)點為尾節(jié)點 3.刪除的節(jié)點是中間節(jié)點
2. 其次:需要獲取要刪除的數(shù)據(jù)所對應的節(jié)點以及他的前一個節(jié)點
3. 刪除節(jié)點,需要將鏈表的長度扣減增加節(jié)點需要長度增加。
### 實現(xiàn)
#### 修改增加方法,增加長度屬性
```java
private transient int size = 0;// 單列表的長度
/**
* 從尾部添加一個節(jié)點
*
* @param data
* 要添加的節(jié)點的數(shù)據(jù)
*/
public void add(Object data) {
// 1.構(gòu)建一個節(jié)點對象
Node node = new Node(data);
if (head == null) {
// 2.判斷鏈表中是否為空 如果為空 則新增的節(jié)點變成頭節(jié)點
head = node;
} else {
// 3.如果鏈表不為空,則需要查詢到尾部節(jié)點
Node rear = findRearNode();
// 4.向尾部節(jié)點添加一個節(jié)點
rear.next = node;// rear肯定不為空
}
size++;
}
// 獲取鏈表的長度
public int size() {
return size;
}
```
#### 編寫刪除的代碼
```java
// 刪除鏈表中的數(shù)據(jù)
public void removeObject(Object data) {
// 賦值為臨時對象
Node temp = head;
//記錄要刪除的節(jié)點的前一個節(jié)點
Node prev = temp;
if (data != null)
while (temp != null) {
if (data.equals(temp.data) && temp.data.hashCode()==data.hashCode()) {
//如果刪除的是頭節(jié)點
if(temp==head){
head=temp.next;//
//如果刪除的是尾部節(jié)點
}else if(temp.next==null){
prev.next=null;
//如果刪除的是中間節(jié)點
}else{
prev.next=temp.next;
}
size--;
break;
}
prev=temp;
//循環(huán)遍歷
temp=temp.next;
}
}
```
代碼解釋:先查詢數(shù)據(jù)在鏈表中是否有,需要循環(huán)遍歷,當數(shù)據(jù)一致 并且hashcode一致時,我們才認為這才是兩個相等的數(shù)據(jù)對象;接著 獲取前一個節(jié)點對象。
## 根據(jù)索引刪除節(jié)點
### 分析
? 根據(jù)索引刪除節(jié)點,也就是說從第幾個位置開始刪除,默認第一個位置索引為0 以此類推。
1. 首先:刪除的節(jié)點的索引不能超過總長度
2. 其次:刪除的節(jié)點 要先找到對應節(jié)點數(shù)據(jù) 再刪除。
### 實現(xiàn)
?
```java
/**
* 根據(jù)指定的索引來刪除鏈表中的數(shù)據(jù)
* @param index
*/
public void removeIndexObject(int index) {
int count=0;
if(index<0 ||index >=size){
System.out.println("越界");
return;
}
Node temp = head;
//記錄前一個節(jié)點
Node prev = temp;
while (temp != null) {
if(count==index){
if(index==0){//說明刪除的是頭節(jié)點
head = temp.next;
}else{
//將要刪除的前一個節(jié)點指向 要刪除節(jié)點的后一個節(jié)點
prev.next=temp.next;
}
size--;//長度-1
break;
}
prev=temp;//記錄上一個節(jié)點
temp=temp.next;
count++;
}
}
```
## 測試
```java
public static void main(String[] args) {
SingleLink singleLink = new SingleLink();
singleLink.add(1);
singleLink.add(2);
singleLink.add(3);
System.out.println("刪除前=================="+singleLink);
singleLink.removeObject(2);
System.out.println("刪除后=================="+singleLink);
}
```
測試效果:
```java
刪除前==================[1,2,3]
刪除后==================[1,3]
```
## 總結(jié)
? 通過刪除節(jié)點我們發(fā)現(xiàn),單鏈表的操作刪除時,需要獲取被刪除的節(jié)點的上一個節(jié)點,獲取上一個節(jié)點相對來時比較麻煩。如果使用雙鏈表,那么這個問題就解決了。而且效率要比單鏈表要高些。下一章,我們來學習下雙鏈表相關的知識,看是如何添加和刪除數(shù)據(jù)的。