我编写了一个递归的双向链接C ++函数来删除具有特定值的双向链表中的所有节点。有可能优化这个吗?谢谢。
struct marynode {
int value;
marynode* next;
marynode* prev;
};
void DoubleLinkedListDeleteMultiple(marynode*& llist, int value){
marynode* tmp = llist;
if (llist == NULL)
return;
if (llist->value == value){
DoubleLinkedListDeleteMultiple(llist->next, value);
if (llist->next == NULL){
marynode* prev = llist->prev;
delete llist;
llist = NULL;
llist = prev;
if (llist)
llist->next = 0;
}
else if (llist->prev == NULL){
marynode* next = llist->next;
delete llist;
llist = NULL;
llist = next;
if (llist)
llist->prev = 0;
}
else{
marynode *x = llist;
marynode *mynext = x->next;
while (x){
if (x->value == value){
marynode* clara = x->next;
marynode* zprev = x->prev;
delete x;
x = NULL;
x = clara;
llist = clara;
if (llist)
llist->prev = zprev;
}
else {
x = mynext;
}
if (mynext){
mynext = mynext->next;
}
}
}
}
else{
DoubleLinkedListDeleteMultiple(llist->next, value);
}
}
答案 0 :(得分:1)
std :: list有什么问题吗?
另外,结构+全局函数?您可能希望使用面向对象的构造,例如成员方法。
为了优化这个特定的代码,我会将你的递归调用改为while循环。
while(llist != NULL) {
if(llist->value == value) {
if(llist->prev) {
llist->prev->next = llist->next;
}
if(llist->next) {
llist->next->prev = llist->prev;
}
node* next = llist->next;
delete llist;
llist = next;
} else {
llist = llist->next;
}
}
答案 1 :(得分:1)
这看起来有点过分......为什么不只是迭代列表只保留好节点?
void DoubleLinkedListDeleteMultiple(marynode*& llist, int value)
{
marynode *newfirst = NULL, *newlast = NULL;
for (marynode *n=llist,*nn; n!=NULL; n=nn)
{
nn = n->next;
if (n->value == value)
{
// Kill it
delete n;
}
else
{
// Append at end of new list
n->prev = newlast; n->next = NULL;
if (newfirst == NULL) newfirst = n;
if (newlast) newlast->next = n;
newlast = n;
}
}
llist = newfirst;
}
如果必须删除大多数元素,上面的代码非常有效,但是如果相反删除的元素很少(因为使用相同的节点重建整个列表),则会进行大量的指针调整。如果用例相反,最好只是迭代节点并使用如下所示的循环删除坏节点
void DoubleLinkedListDeleteMultiple(marynode*& llist, int value)
{
marynode *prev = NULL;
marynode *n = llist;
while (n)
{
if (n->value == value)
{
// Kill it
marynode *nn = n->next;
delete n;
n = nn;
// Fix links
if (prev) prev->next = n; else llist = n;
if (n) n->prev = prev;
}
else
{
// Move over to next one
prev = n; n = n->next;
}
}
}
另一种选择是尝试针对这两种极端情况进行优化,基本上是使用最紧密的循环复制或删除“运行”中的元素,并且只在运行结束时执行最终需要的修复...
void DoubleLinkedListDeleteMultiple(marynode *& list, int value)
{
marynode *n = list;
marynode *prev = NULL;
while (n)
{
if (n->value == value)
{
// bad element: delete it and all following
// consecutive bad elements
do {
marynode *nn = n->next;
delete n;
n = nn;
} while (n && n->value == value);
// fix the links only once per run
if (prev) prev->next = n; else list = n;
if (n) n->prev = prev;
}
else
{
// good element; just skip this and all
// following good elements
do {
prev = n;
n = n->next;
} while (n && n->value != value);
}
}
}
警告:所有呈现的代码都未经过测试(甚至尚未编译......)
答案 2 :(得分:1)
为什么不在那里进行一些重构并提取你想要完成的事情的本质?
类似(未经测试且未编译)
void dll_link_nodes(node * theFirstNode, node *theNextNode){
theFirstNode->next = theNextNode;
theNextNode->prev = theFirstNode;
}
void dll_delete_node( marynode * theNode ){
dll_link_nodes(theNode->prev, theNode->next);
delete theNode;
}
node* dll_get_next_node (node* theNode){
return theNode != NULL ? theNode->next : NULL;
}
inline int dll_node_get_value(node *n){
return n->value;
}
void DoubleLinkedListDeleteMultiple(node*& llist, int value){
node * iter = llist;
while (iter != NULL){
if ( dll_node_get_value(iter) == value) {
node * target = iter;
iter = dll_get_next_node(iter);
dll_delete_node(target);
}else
{
iter = dll_get_next_node(iter);
}
}
}
答案 3 :(得分:0)
早上好,昨晚我找到了一种方法,通过更改2行来优化DoublyLinkedListDeleteMultiple的C ++递归实现(请参阅//优化)。感谢大家的回答和评论。
void DoubleLinkedListDeleteMultiple(marynode *& llist,int value){ marynode * tmp = llist;
if (llist == NULL)
return;
if (llist->value == value){
DoubleLinkedListDeleteMultiple(llist->next, value);
if (llist->next == NULL){
marynode* prev = llist->prev;
delete llist;
llist = NULL;
llist = prev;
if (llist)
llist->next = 0;
}
else if (llist->prev == NULL){
marynode* next = llist->next;
delete llist;
llist = NULL;
llist = next;
if (llist)
llist->prev = 0;
}
else{
marynode *x = llist;
marynode *mynext = x->next;
int counter(0);
while (x && counter++ < 1){ // Optimization
if (x->value == value){
marynode* clara = x->next;
marynode* zprev = x->prev;
delete x;
x = NULL;
x = clara;
llist = clara;
if (llist)
llist->prev = zprev;
}
else {
x = mynext;
}
if (mynext){
mynext = mynext->next;
}
}
}
}
else{
DoubleLinkedListDeleteMultiple(llist->next, value);
}
}