C语言数据结构相关编程->链表001题

环境:win10,codeblocks
最近跟着本科生一起学习下数据结构,把解答的一些问题push上来。由于本人很久很久没使用过C语言,被指针弄的头痛,所以有些解题思路比较绕不是因为蠢。而是程序的莫名报错,不断换方法AC的结果。
- 题一,将两个非递减的有序链表合为一个非递减的有序链表(要求利用原来两个链表的存储空间,不另外占用其他空间,表中不允许有重复数据)
- 算法思路:本来是想在一个函数中将链表2依次插入到链表1中去的,然后各种情况需要考虑,然后简单起见。编写了一个insertNode(linkList* head,linkList* item)函数,然后就将链表2中的节点依次插入就行了。
- 考虑的情况:因为不能使用额外的空间,不是很多人使用数组或者神马的来存储,你会遇到相应的问题。比如你将链表2插入到链表1,如果链表2的第一个元素比链表1小怎么办,那就涉及到表头插入,如果链表2的元素都比链表1的第一个小怎么办等等问题。为了编程的可重用性,编写一个插入函数是有必要的。
- 废话不多说直接贴代码:(程序核心代码其实并不多,只是博主有强迫症,喜欢把每个细节都写好.这样子新手看起来就容易点,起来可以直接跑起来,如果跑不起肯定是我在CSDN上传删注释的时候弄坏了…源文件的注释更多..而且一个文件里用了多个方法,直接po上来会晕掉去的..)

#include<stdio.h>
#include<stdlib.h>
//定义节点
typedef struct node{
    int data;
    struct node *next;
}linkList;
//构造链表
linkList* createLinkedList(linkList* head)
{
    int data[5];//为方便操作定义一个大小为5的链表
    int i = 0;
    linkList* cur = head;//定义一个cur当前节点来遍历整个链表
    while(i < 5)
    {
    linkList *temp = (linkList*)malloc(sizeof(linkList));//定义一个temp节点来存储输入数据
        scanf("%d",&data[i]);
        temp->data = data[i];//临时节点保存数据
        temp->next = NULL;
        cur->next = temp;//遍历指针指向临时节点
        cur = temp;//向后移一位
        i++;
    }
    return head;
}
//插入节点函数
linkList* insertNode(linkList* head,linkList* item)
{
    linkList* cur = head->next;//cur指向链表头结点后的元素
    linkList* pre =NULL;//pre始终在cur的前面,因为插入有一种情况就是在pre和cur之间插入的
    while(cur->data <= item->data && cur!=NULL)//在当前的值比item小时进入while循环
    {
        if(cur->next == NULL)//意味链表到最后了,这时候又满足比item->data小,则可以把item插入到最后一个
        {
            cur->next = item;
            return head;//直接返回head节点,函数结束
        }
        pre = cur;//保存cur当前点
        cur = cur->next;//cur指向下一个节点
    }
    //如果经过了上述的while循环,cur的位置没变,说明item->data比head->next->data还小,所以插入在head和cur之间。
    if(cur == head->next)
    {
        item->next = cur;
        head->next = item;
        return head;//返回head,结束函数
    }
    pre->next = item;//正常情况,在pre和cur之间插入item
    item->next = cur;
    return head;//返回head,结束函数
}

linkList* sortLinkedList(linkList* head1,linkList* head2)
{
    //萌新博主之所以下面的指针声明如此浩大,是因为这几天被没malloc地址的野指针给玩坏了,程序各种异常。。
    linkList* head = (linkList*)malloc(sizeof(linkList));
    linkList* cur = (linkList*)malloc(sizeof(linkList));
    linkList* newLink =  (linkList*)malloc(sizeof(linkList));
    linkList* pre =  (linkList*)malloc(sizeof(linkList));
    linkList* print =  (linkList*)malloc(sizeof(linkList));
    //简单的判断,不做无谓的牺牲
    if(head1 == NULL)
    {
        return head2;
    }
    else if(head2 ==NULL)
    {
        return head1;
    }
    head = head1->next;//指向链表1的头结点后的第一个节点
    cur = head2->next;//同上
    while(cur != NULL)
    {
        pre = cur->next;//保留cur的下一个节点,发现单词用错了。。应该用next的。。你们懂就行
        //下面的语句也许你会觉得加起来很傻X,是有用意的,即把每一个节点跟后面断开。不断开会在某些情况出问题的
        cur->next = NULL;  //跟下一个节点断开
        newLink = insertNode(head1,cur);//直接调用,插入cur节点
        //下面来打印以下每次插入后的结果,建议萌新多写printf来打印结果,然后在纸上慢慢分析错误。
        print = newLink->next;
        while(print != NULL)
        {
        printf("%d->\t",print->data);
        print = print->next;
        }
        cur = pre;//cur指向下一个
        head1 = newLink;//更新head1
    }
    return newLink;
}
int main()
{
    linkList *head1 = (linkList*)malloc(sizeof(linkList));
    linkList *head2 = (linkList*)malloc(sizeof(linkList));
    linkList *link1 = createLinkedList(head1);
    linkList *link2 = createLinkedList(head2);
    linkList *print1 = link1->next;
    linkList *print2 = link2->next;
    while(print1 != NULL)
    {
        printf("%d->\t",print1->data);
        print1 = print1->next;
    }
    while(print2 != NULL)
    {
        printf("%d->\t",print2->data);
        print2 = print2->next;
    }
    linkList *newLink = sortLinkedList(link1,link2);
    linkList *print = newLink->next;
    while(print != NULL)
    {
        printf("%d\t",print->data);
        print = print->next;
    }
    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值