数据结构单链表代码实战

   上一期我给大家讲解和介绍了单链表的头插法和尾插法,今天我将为大家带来综合性的代码考研真题实战,依次作为一个机会来锻炼自己的代码能力。此次我们将实战考研2019年的408。

首先我们先分析题干理解题干,重点词带头结点的单链表,并且空间复杂度为O(1),分析最初的L与L~的区别。下面我们开始正式实战:

首先设计思路:(1)空间复杂度为O(1)的意思为我们设计的程序不会在过多的去申请空间,如果在原来链表的基础上重新申请了空间则空间复杂度不为O(1)。

(2)观察线性表中数据的变化,可知将原有的单链表一分为二,然后将后半部分的单链表逆放置,最后将逆放置的单链表重新插入前半部分的表,从而形成一个新的单链表。

(3)在将线性表一分为二,我们可以使用双指针法进行整个单链表的便利,从而使其空间复杂度始终为(1),两个指针的运行思路为,其中一个指针走两步(P2),另外一个指针走一步(P1),这个地方不好理解,希望读者在阅读过程中自己画图去切身的感受,学习最重要的就是知行合一,大家一定要自己去动手画图理解感悟。

(4)我们需要一个新的头结点去接收我们将原来单链表断开的后半部分,然后使这个新的单链表原地逆置,原地逆置我们需要用到三个指针,代码中分别用的为r、s、t。

(5)最后将原地逆置好的单链表按照题中的意思进行插入组合,最后组合完成释放新申请的头结点,释放新申请的头结点是为了代码的严谨性,在真正考场上为了赶时间我们可以不去释放。

代码的实现:

(1)在上一期我们学会了尾差法创建一个单链表,详情去看上一篇文章这里不做过多赘述。

(2)下面我们开始将我们创建好的单链表一分为二

我们写了一个函数,首先注意C++语言的引用用法,上一篇文章已经说清楚这里不再赘述,

void find_middle(LinkList L,LinkList &L2)
{//首先声明我把代码放到这里不是为了让大家复制粘贴的,更多的是去了解思路,感悟方法。
    L2=(LNode *)malloc(sizeof(LNode));//第二条链表的头结点
    LinkList p1,p2;//双指针法可以解决很多题型,是考研初试常考
    p1=p2=L->next;//让我们所申请的两个指针都指向单链表的第一个节点
    while(p2!=NULL){
        p2=p2->next;//要时刻判断指向是否为空,p2指针遍历走第一步
        if(p2==NULL)//为了防止程序崩溃
        {
            break;
        }
        p2=p2->next;p2指针遍历走第二步
        if(p2==NULL)//为了防止程序崩溃
        {
            break;
        }
        p1=p1->next;//p1指针遍历走第一步
    }
    L2->next=p1->next;//由L2头结点指向后面一半链表
    p1->next=NULL;//前一个节点的最后一个节点的尾部节点为null;
}

这个函数就让我们实现了L单链表一分为二,下面我们开始原地逆置L2链表

void reverse(LinkList L2){
    LinkList r,s,t;//定义三个指针
    r=L2->next;
    if(r==NULL)
    {
        return;
    }
    s=r->next;
    if(s==NULL)
    {
        return;
    }
    t=s->next;
    while(t){
        s->next=r;
        r=s;
        s=t;
        t=t->next;
    }
   s->next=r;
    L2->next->next=NULL;
    L2->next=s;
 };//希望大家好好画图理解,感悟。

下面我们实现插入合并

void merge(LinkList L,LinkList L2)//合并两个链表
{
    LinkList pcur,p,q;
    pcur=L->next;//pcur始终指组合后的链表尾部,也就是新链表的尾部
    p=pcur->next;
    q=L2->next;//q指向L2第一个结点
    while(p!=NULL&&q!=NULL){
        pcur->next=q;
        q=q->next;//指向L2的下一个链表
        pcur=pcur->next;
        pcur->next=p;
        p=p->next;
        pcur=pcur->next;
    }
    if(p!=NULL){
        pcur->next=p;
    }
    if(q!=NULL){
        pcur->next=q;
    }
}

这三个函数写完我们本次大题就算结束了,大家一定要动手画思路图,然后敲代码实现。

我们终会成为更好的自己,充满希望的活下去。

  • 30
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
下面是一个使用C语言实现的单链表的完整代码示例: ```c #include <stdio.h> #include <stdlib.h> // 定义链表节点结构 typedef struct Node { int data; struct Node* next; } Node; // 初始化链表 Node* initList() { Node* head = (Node*)malloc(sizeof(Node)); head->next = NULL; return head; } // 在链表末尾添加节点 void append(Node* head, int data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->next = NULL; Node* cur = head; while (cur->next != NULL) { cur = cur->next; } cur->next = newNode; } // 在链表指定位置插入节点 void insert(Node* head, int index, int data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->next = NULL; Node* cur = head; for (int i = 0; i < index && cur->next != NULL; i++) { cur = cur->next; } newNode->next = cur->next; cur->next = newNode; } // 删除链表指定位置的节点 void deleteNode(Node* head, int index) { if (index < 0 || index >= length(head)) { printf("删除位置不合法\n"); return; } Node* cur = head; for (int i = 0; i < index && cur->next != NULL; i++) { cur = cur->next; } Node* delNode = cur->next; cur->next = delNode->next; free(delNode); } // 获取链表的长度 int length(Node* head) { int len = 0; Node* cur = head->next; while (cur != NULL) { len++; cur = cur->next; } return len; } // 打印链表 void printList(Node* head) { Node* cur = head->next; while (cur != NULL) { printf("%d ", cur->data); cur = cur->next; } printf("\n"); } int main() { Node* head = initList(); // 初始化链表 append(head, 1); // 在末尾添加节点 append(head, 2); append(head, 3); printList(head); // 打印链表: 1 2 3 insert(head, 1, 4); // 在指定位置插入节点 printList(head); // 打印链表: 1 4 2 3 deleteNode(head, 2); // 删除指定位置的节点 printList(head); // 打印链表: 1 4 3 int len = length(head); // 获取链表的长度 printf("链表长度为: %d\n", len); // 输出:链表长度为: 3 return 0; } ``` 以上是一个基本的单链表实现,包括初始化链表、在链表末尾添加节点、在指定位置插入节点、删除指定位置的节点、获取链表长度等操作。最后通过一个示例展示了如何使用这些操作来对链表进行操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值