您的位置:首页 > 其它

从无头单链表中删除节点

2012-02-20 19:42 204 查看
题目:在一个给定的单向链表中,如何遍历一次删除特定的节点

解法:这是一个典型的逆向思维问题,正常的删除需要把当前节点的前面节点和后面节点链接起来,再删除当前节点,完成任务。当前节点的后续节点比较容易得到,但困难的是无法得到当前节点的前面节点,逆向思维的结果是不删除当前节点,而是将后面节点的数据拷贝到当前节点,转而删除当前节点的后面节点,从而完成删除操作。代码如下:

#include <stdio.h>
#include <stdlib.h>
template<typename T>
class ListNode {
public:
ListNode(const T& value) : value_(value), next_(NULL) {}
T value_;
ListNode* next_;
};
template<typename T, typename VisitFun>
class List {
public:
List() : head_(NULL), size_(0){};
void Insert(const T& value) {
if (head_) {
ListNode<T>* next = head_;
head_ = new ListNode<T>(value);
head_->next_ = next;
} else {
head_ = new ListNode<T>(value);
}
size_++;
}
size_t Size() {
return size_;
}
bool Delete(size_t index) {
if (index > size_) {
return false;
}
ListNode<T>* current = head_;
int count = 1;
while (count < index) {
current = current->next_;
count++;
}
if (current->next_ == NULL) {
delete current;
current = NULL;
} else {
ListNode<T>* next = current->next_;
current->value_ = next->value_;
current->next_ = next->next_;
delete next;
}
return true;
}
void PrintList(VisitFun visit_fun) {
ListNode<T>* current = head_;
while(current) {
visit_fun(current->value_);
current = current->next_;
}
}
private:
ListNode<T>* head_;
size_t size_;
};
void Print(int value) {
printf("%d ", value);
}

typedef void (*visit_fun)(int value);

int main(int argc, char** argv) {
List<int,visit_fun> my_list;
const int kListSize = 10;
for (int i = 0; i < kListSize; ++i) {
my_list.Insert(rand());
}
my_list.PrintList(Print);
printf("\n");
int rand_index = random() % my_list.Size();
printf("to delete:%d\n", rand_index);
my_list.Delete(rand_index);
my_list.PrintList(Print);
printf("\n");
}


参考文献

编程之美3.4
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: