【线性表】双向链表的基本操作 指定结点交换

本文介绍了双向链表的基本操作,包括如何创建、打印链表以及实现指定值节点与其前驱节点的交换功能。示例代码详细展示了这些操作的实现,如插入新节点、删除节点以及在链表中查找和交换特定值的节点。通过示例代码,读者可以理解双向链表的数据结构和操作方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.双向链表的基本操作

2.双向链表的创建和打印

3.指定值为x的结点与其前驱结点交换


1.双向链表的基本操作

#include <iostream>
using namespace std;

typedef int Elemtype;
typedef struct LinkNode {
    Elemtype data;
    LinkNode *next, *previous;
} * DLIST, *Node;

void Delete(Node p)
{ //删除p结点
    if (p->previous != NULL) {
        p->previous->next = p->next;
    }
    if (p->next != NULL) {
        p->next->previous = p->previous;
    }
    delete p;
}

void MakeNull(DLIST &DL)
{ // 将双向链表置空
    delete DL->next;
    DL = new LinkNode;
    DL->next = NULL;
    DL->previous = NULL;
}

void Insert(Elemtype x, Node p)
{ //在结点p后添加结点q
    Node q = new LinkNode;
    q->data = x;
    q->next = p->next;
    p->next->previous = q;
    p->next = q;
    q->previous = p;
}

Node Locate(Elemtype x, DLIST DL)
{ //定位第一个值为x的元素
    Node p = DL;
    while (p->next != NULL) {
        if (p->next->data == x)
            return p->next;
        else
            p = p->next;
    }
    return p->next;
}

2.双向链表的创建和打印

void CreatDList(DLIST &DL, int n)
{
    int x;
    Node p = DL;
    p->previous = NULL;
    p->next = new LinkNode;
    p->next->next = NULL;

    for (int i = 0; i < n; i++) {
        cin >> x;
        Insert(x, p);
    }
}

void PrintDList(DLIST DL)
{
    Node p = DL;
    while (p->next != NULL) {
        cout << p->next->data << "\t";
        p = p->next;
    }
    cout << endl;
}

3.指定值为x的结点与其前驱结点交换

int Swap(Elemtype x, DLIST &DL)
{ //若链表中存在元素值为x的结点,将其与其前驱结点进行交换
    Node p1, p2;
    p1 = Locate(x, DL);
    if (p1 == NULL)
        return 0;
    else {
        Insert(x, p1->previous->previous);
        Delete(p1); //先将新x插入前驱结点的前面,再删除旧x
        return 1;
    }
}

int main()
{
    DLIST DL = new LinkNode;
    cout << "输入5个数据创建双向链表: ";
    CreatDList(DL, 5);
    PrintDList(DL);
    Swap(2, DL);
    PrintDList(DL);
}

<think>好的,用户想要寻找与线性表链表相关的C语言编程练习题。我需要先回顾一下用户提供的引用内容,看看里面有没有相关的题目或者示例可以推荐。 首先,引用[1]提到链表去重的双循环法,这可能对应一个练习题,比如如何实现链表的去重操作。引用[2]和[5]讨论了链表的基本结构和实现,这可能涉及创建链表、插入删除节点等基础题目。引用[3]和[4]提到了顺序表的操作,比如删除特定元素,这些可以作为顺序表的练习题。 接下来,我需要整理这些引用中的题目,补充一些常见的练习题类型。例如,链表反转、合有序链表、检测循环等经典问题。同时,确保题目涵盖顺序表和链表两种结构,涉及基本操作如插入、删除、查找,以及更复杂的算法应用。 还要注意题目的难度层次,从基础到进阶,让用户逐步提升。例如,先练习创建和遍历链表,再尝试较难的如环检测或复杂操作。此外,引用中的代码示例可以作为参考答案,但需要确保用户自己实现。 最后,需要按照用户的要求,用中文清晰列出问题,在相关部分添加引用标识。确保每个问题对应一个具体的编程任务,涵盖不同的知识点,如时间复杂度优化、空间复杂度控制等。</think>以下是与线性表链表相关的C语言编程练习题及知识点解析,涵盖基础操作和进阶应用: ### 一、顺序表练习题 1. **删除特定元素** 设计时间复杂度$O(n)$、空间复杂度$O(1)$的算法,删除顺序表中所有值为`item`的元素[^4]。 **代码提示**:双指针覆盖法实现原地修改。 2. **合有序顺序表** 将两个升序排列的顺序表合为一个新表,要求时间复杂度$O(m+n)$。 3. **逆置顺序表** 不借助额外空间,将顺序表元素逆序存放。 --- ### 二、单链表练习题 1. **链表反转** 将单链表所有结点的指针方向反向(要求空间复杂度$O(1)$)。 2. **删除重复结点** 使用双循环法对带头结点的单链表进行去重操作[^1]。 **示例代码片段**: ```c void remove_duplicates(Linklist head){ LNode *p = head->next; while (p != NULL) { LNode *q = p; while (q->next != NULL) { if (q->next->data == p->data) { LNode *temp = q->next; q->next = temp->next; free(temp); } else { q = q->next; } } p = p->next; } } ``` 3. **查找中间结点** 使用快慢指针法,仅遍历一次链表即可找到中间结点。 --- ### 三、双向链表练习题 1. **结点交换** 实现双向链表指定结点与其前驱结点交换操作[^3]。 **关键步骤**:需修改相邻4个结点的指针关系。 2. **双向循环链表插入** 在双向循环链表的特定位置插入新结点,保持链表完整性。 --- ### 四、综合应用题 1. **链表环检测** 判断单链表是否存在环,找出环的入口(Floyd龟兔算法)。 2. **多项式相加** 用链表实现两个一元多项式的相加运算,要求合同类项。 3. **LRU缓存实现** 结合哈希表和双向链表,设计时间复杂度$O(1)$的LRU缓存淘汰算法。 --- ### 知识要点 1. **指针操作**:链表的核心是掌握`->`运算符和指针传递机制 2. **内存管理**:动态分配需配对使用`malloc`/`free` 3. **边界处理**:特别注意头结点、尾结点的特殊操作 4. **复杂度分析**:如双指针法能将时间复杂度从$O(n^2)$优化到$O(n)$ §§相关进阶问题§§ 1. 如何用链表实现大整数加法? 2. 循环链表在操作系统中有哪些应用场景? 3. 哈希表与链表结合能解决哪些经典问题?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值