很好地从链接列表中删除项目

时间:2019-07-10 09:44:56

标签: javascript java c linked-list

this TED演讲中,莱纳斯·托瓦尔兹(Linus Torvalds)在从链接列表中删除项目的示例中显示出“差”和“好”的编程品味。

味道不好的例子:

enter image description here

这里有好味道:

enter image description here

这里的重点是不良品味示例中的if语句。

我不是C / C ++开发人员,不幸的是,我的想法是“不好”。

我的问题在这里:是否可以在不使用C样式指针的编程语言上不使用if特殊情况的情况下编写“智能”解决方案? 例如在Java或javascript上。

2 个答案:

答案 0 :(得分:1)

关于您的问题:

是否可以编写“智能”解决方案,而无需在没有C样式指针的编程语言上使用特殊情况的if语句

答案:

编写代码时几乎所有可能。

答案 1 :(得分:1)

我将您的代码段扩展到整个.c文件,以使其在上下文中更易于理解:

struct node {
    int data;
    struct node* next;
}

typedef struct node nodde_t;

node_t* head;

/*bad code*/
remove_list_entry(node_t* entry){
    node_t* prev = NULL;
    node_t* walk = head;

    while(walk != entry){
        prev = walk;
        walk = walk->next;
    }

    if(!prev)
        head = entry->next;
    else
        prev->next = entry->next;
}

/*good code*/
remove_list_entry(node_t* entry){
    
    node_t* indirect = &head;

    while ((*indirect) != entry)
        indirect = &(*indirect)->next;

    *indirect = entry->next;
}

int main(){

    node_t n1, n2, n3;
    
    n1.data = 45;
    n2.data = 8;
    n3.data = 32;

    head = &n1; 
    n1.next = &n2;
    n2.next = &n3;
    n3.next = NULL;
    
    remove_list_entry(&n2); /* instead : n1.next = &n3; */

    return 0;

}

为简单起见,我决定将Integers作为数据。 typedef的目的是能够写入node_t而不是struct node。是的,在C语言中,每次使用类型节点时都必须编写结构字。如果您甚至不熟悉指针,请考虑用Java编写的这段代码,用引用而不是指针(除非我没有在Java中提供主要的方法):

public class MyList {

    class Node {
        int value;
        Node next; // recursive
    }

    Node head;
    
    
    void add(int newvalue) {
        Node newnode = new Node();
        newnode.value = newvalue;
    
        Node indirect = head;
    
        while (indirect.next != null)
            indirect = indirect.next;
            
        indirect.next = newnode;
    }
    
    /* good code */
    void remove_list_entry_good(Node entry) {

    Node indirect = head;

        while (indirect != entry)
            indirect = indirect.next; 

        indirect = entry.next;
    }

    /* bad code */
    void remove_list_entry_bad(Node entry) {
        Node prev = null;
        Node walk = head;

        while (walk != entry) {
            prev = walk;
            walk = walk.next;
        }

        if (prev == null)
            head = entry.next;
        else
            prev.next = entry.next;
    }

}

Node类使用递归定义,例如反复调用自身的方法。如果您想知道为什么将Node类写在MyList类内部,则称为私有类。

修改 我在Java中的“好代码”无法正常工作,但是我在C语言中发现了一些非常有趣的东西。间接类型必须为双星的node_t **。不知道这意味着什么,但是它有效。在网站上找到了双星产品:

/*good code*/
remove_list_entry(node_t* entry) {

    node_t** indirect = &head;

    while ((*indirect) != entry)
        indirect = &(*indirect)->next;

    *indirect = entry->next;
}

修改 哇,这花了我很长时间!我在网上发现了一些既有效又简单的东西! https://www.dineshonjava.com/delete-given-node-from-singly-linked-list/

void remove_list_entry_good(Node entry) {
    Node temp = entry.next; 
    entry.value = temp.value; 
    entry.next = temp.next; 
    temp = null; 
}

令人讨厌的(希望如此)最近一次更新:

我设法做到了...

这是代码,它终于可以工作了。

void remove_list_entry_good(Node entry) {


    Node indirect = head;

    while (indirect.next != entry)
        indirect = indirect.next;

    indirect.next = entry.next;


}