c - 排序插入链表

标签 c linked-list sorting

迎角,

12 小时以来,我一直在尝试调试循环链表中的问题。该函数采用具有开始和光标字段的 ADT。初始虚拟单元格指向自身。插入元素。不允许重复元素。

    int setInsertElementSorted(setADT buffer, setElementT E)
    {
        bool isUnique = true;
        cellT *previous;

        previous = buffer->start;
        buffer->cursor = buffer->start->next;

        while(buffer->cursor != buffer->start){
            if(buffer->cursor->value == E){
                isUnique = false;
            } else if(E < buffer->cursor->value)
                break;
              else {   
                previous = buffer->cursor;
                buffer->cursor = buffer->cursor->next;
            }
        }

        if(isUnique != false){
            cellT *newNode = malloc(sizeof(cellT));
            newNode->value = E;
            previous->next = newNode;
            newNode->next = buffer->cursor;

            buffer->count++;
            return (buffer->count);   
            }
    }

代码接受一系列整数,然后将它们排序到 LL 参数中。应该用于集合(因此没有重复条目)。

输出:9、8、7、6、5、4、3、2、1

是.. 3, 4, 5, 6, 7, 8, 9(前两个值发生了什么?)

当输入类似:7、3、5、1、9、2

out 只有 7、9(所以它不能处理由多个分隔的值..o.O)

附加信息:

typedef struct cellT {
    int value;
    struct cellT *next;
} cellT;

struct setCDT{
    int count;
    cellT *start;
    cellT *cursor;   
};

setADT setNew()
{
    setADT newNode = malloc(sizeof(struct setCDT));
    newNode->start = newNode->cursor = malloc(sizeof(cellT));
    newNode->start->next = newNode->cursor->next = newNode->start;
    newNode->count = 0;
    return (newNode);
}

setADT 是指向 setCDT 的指针类型。然而,setElementT 只是一个简单明了的 int。抱歉含糊不清。

最佳答案

一些观察:

while(buffer->cursor != buffer->start && buffer->cursor->value < E){
    if(buffer->cursor->value == E) // never true

value == E在第一个循环中永远不会为真,因为循环条件有 value < E ,因此遇到等于 E 的值会停止迭代。将循环条件更改为 <= E简单地 return如果找到重复而不是使用 flag .

flag == false所在的路径也不返回值(尽管由于上述错误,目前无法访问),以及为 newNode 分配的内存如果错误与 flag 泄漏是固定的,E已经存在于列表中。

以下if似乎毫无意义,并且由于没有 {else 之后缩进非常误导:

if(buffer->cursor != buffer->start){
    newNode->next = buffer->cursor; // would be harmless in both branches
    previous->next = newNode;       // done in both branches
} else                              // always using { } would make this clear
    previous->next = newNode;
    buffer->count++;
    return (buffer->count);

此外,不要键入 def setADT作为指针类型,它只是误导并与 New(setADT) 等结构相结合几乎肯定会导致错误。

同时在 setNew ,因为只有一个节点,替换newNode->start->next = newNode->cursor->next = newNode->start;newNode->start->next = newNode->start ;

变更摘要:

int setInsertElementSorted(struct setCDT * const buffer, const int E) {
    cellT *newNode;
    cellT *previous = buffer->start;
    buffer->cursor = previous->next;

    while (buffer->cursor != buffer->start && buffer->cursor->value <= E) {
        if (buffer->cursor->value == E) {
            return buffer->count; // duplicate value
        }
        previous = buffer->cursor;
        buffer->cursor = buffer->cursor->next;
    }
    if ((newNode = malloc(sizeof(*newNode)))) {
        newNode->value = E;
        newNode->next = buffer->cursor;
        previous->next = newNode;
        buffer->count++;
    }
    return buffer->count;
}

如果错误仍然存​​在,则错误可能出在其他地方。

要测试的代码:

int main (int argc, char **argv) {
    struct setCDT *list = setNew();
    for (int i = 1; i < argc; ++i) {
        setInsertElementSorted(list, atoi(argv[i]));
    }
    list->cursor = list->start;
    while ((list->cursor = list->cursor->next) != list->start) {
        (void) printf("%d\n", list->cursor->value);
    }
    return EXIT_SUCCESS;
}

关于c - 排序插入链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31628521/

相关文章:

c++ - 删除仅给定节点的单向链表中间的节点。 C++

c++ - 这个特定用例的一个很好的排序算法

java - Applet 中的 Paint 方法(Java 中的排序算法)

c - memset 无法正常工作

c - 杀死一个进程最终会挂起

java - 循环链表逻辑

c - 无法使用指向该变量的指针更改其他函数中局部变量的状态

c++ - list::sort 更改值 C++

c++ - 动态内存分配在哪里?

客户端套接字无法使用轮询/选择接收数据