数据结构-链表题(23.4.16)

226 阅读1分钟

递归删除指定值结点

设计一个递归算法,删除不带头结点的单链表l中所有值为x的算法。

代码

void deleteElem_DG(node *&l, int data) {
    if (l == NULL) return;
    node *r = l, *s;
    s = l->next;
    if (r->data == data) free(r);
    return deleteElem_DG(s, data);
}

题解

一个很简单的链表递归,每一次递归删除当前结点的data值与和参数data一样的结点,并让函数参数l为指向链表的下一个结点,直到参数l指向为NULL时返回。与循环法按值删除链表结点的思路基本一致,只是题目要求用递归。

反向遍历输出链表

设l是带头结点的单链表,编写算法实现从尾到头反向输出每个结点的值。

代码

void display_RE(node *&l) {
    stack<int> stack;
    node *s = l->next;
    while (s != NULL) {
        stack.push(s->data);
        s = s->next;
    }
    while (!stack.empty()) {
        cout << stack.top() << " ";
        stack.pop();
    }
    cout << endl;
}

题解

这里用到了一个stack,即使不用栈,也能用数组去模拟实现,这里为了方便观看就使用了。

这道题也很简单,设一个指针s遍历每一个结点,每经过一个结点就将该结点的data压入到栈中,等到s遍历完成后通过栈将栈顶元素依次输出并弹出,直到栈空。这样输出的结果就是原来链表顺序的反向。

在链表中删除最小值结点

试编写在带头结点的链表l中删除一个最小值结点的高效算法(假设最小值结点唯一)

代码

void deleteElem_MIN(node *&l) {
    node *min_node, *s = l->next, *r;
    int min = INT_MAX;
    while (s != NULL) {
        if (s->data < min) {
            min = s->data;
            min_node = s;
        }
        s = s->next;
    }
    r = min_node->next;
    s = l->next;
    if (r == NULL) {
        while (s->next != min_node) {
            s = s->next;
        }
        s->next = NULL;
        free(min_node);
    } else {
        min_node->data = r->data;
        min_node->next = r->next;
        free(r);
    }
}

题解

在链表l中依次遍历寻找data值最小的结点,并将结点记录下来(min_node)。判断min_node的next指针是不是指向NULL,如果不是,只需要把下一个结点的data值赋值到min_node结点的data中,并删除掉下一个结点即可;如果是,则需要遍历找到该结点的前一个结点,按常规方式删除min_node结点。