0%

如何從一個Singly linked linear list中刪除資料

要從一個singly lisked linerar list中刪除文件,最簡單的方式莫過於用一個指標指向前一個node,如果現在的item需要刪除,將前面一項item指向後面的item即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
typedef struct node  
{
struct node * next;
} node;

node *remove_if(node * head, remove_fn rm)
{
for (node *prev = NULL, *curr = head; curr != NULL; )
{
node * next = curr->next;
if (rm(curr))
{
if (prev)
prev->next = curr->next;
else
head = curr->next;
free(curr);
}
else
prev = curr;
curr = next;
}
return head;
}

有人提出了更精巧的方法,利用two star pointer來達成,也就是指標的指標。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void remove_if(node **head, remove_fn rm)
{
for (node** curr = head; *curr; )
{
node * entry = *curr;
if (rm(entry))
{
*curr = entry->next;
free(entry);
}
else
curr = &entry->next;
}
}

在C++11的年代,增加了forward_list,省得自己造輪子的麻煩。
以下是forward_list的介紹。

std::forward_list is a container that supports fast insertion and removal of elements from anywhere in the container. Fast random access is not supported. It is implemented as singly-linked list and essentially does not have any overhead compared to its implementation in C. Compared to std::list this container provides more space efficient storage when bidirectional iteration is not needed.

以下是一個示範程式,裡面同時使用了lambda expressionRange-based for loop,日後有時間在寫。

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <forward_list>
int main()
{
std::forward_list<int> list = {8, 7, 5, 3, 2, 6, 4};
list.remove_if([](int n) { return n % 2 == 0; });

for (int n : list) {
std::cout << n << ' ';
}
std::cout << '\n';
}