2021年12月15日学习总结

一.链表学习

一:链表是什么
1、链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,有一系列结点(地址)组成,结点可动态的生成。

2、结点包括两个部分:(1)存储数据元素的数据域(内存空间),(2)存储指向下一个结点地址的指针域。

3、相对于线性表顺序结构,操作复杂。

4.链表分为 (1)单链表 (2)双链表 (3)单向循环链表 (4)双向循环链表

早上第一节物理课确实学不会,就索性打开电脑开始AC链表。

因为太久没有使用链表,所以早上在做链表删重时花多了一点时间来完成。

题目如下

题目描述

有两个链表a和b,从a、b中删除它两重复的元素(只要重复就删除),并对删除后的a链表进行升序排序,b链表进行降序排序。a 的长度为m,b 的长度为n

输入格式

输入a,b的长度m,n

a、b链表

输出格式

处理后的a、b链表

样例输入content_copy

9
6
1 2 3 4 5 6 7 8 6
5 6 7 10 0 5

样例输出content_copy

1 2 3 4 8 
10 0 

提示/说明

 本题是多组输入。

代码如下

#include<stdio.h>
#include<malloc.h>
#define NEW (struct Node*)malloc(sizeof(struct Node))
 typedef struct Node{
     int data;
     struct Node * next;
 }NODE,*PNODE;
PNODE build(int num)
 {
     PNODE head=NULL;
     PNODE p1=head;
    PNODE p2=NULL;
    int data;
     for(int i=0;i<num;i++)
     {
         scanf("%d",&data);
         if(head==NULL){head=NEW;p1=head;head->data=data;}
         else{p2=NEW;p1->next=p2;p2->data=data;p1=p2;p1->next=NULL;}
    }
    p2=NEW;
    p2->next=head;
    head=p2;
    head->data=-1;
    return head;
 }
 int dele(PNODE head,int num)
 {
     PNODE prep=head;
     PNODE p=head->next;
    int flag=0;
     while(p!=NULL)
     {
         while(p!=NULL&&p->data==num){prep->next=p->next;p=prep->next;flag=1;}
         if(p!=NULL){prep=p;p=p->next;}
     }
     return flag;
 }
 void judge(PNODE headm,PNODE headn)
 {
     for(PNODE p=headm->next,prep=headm;p!=NULL;prep=p,p=p->next)
     {
        if((dele(p,p->data)+dele(headn,p->data))>0) {prep->next=p->next;p=prep;}
    }
    for(PNODE p=headn->next;p!=NULL;p=p->next)
    {
        dele(headm,p->data);
        dele(p,p->data);
    }
 }
 void PRINT(PNODE head)
 {
     for(PNODE p=head->next;p!=NULL;p=p->next)
     {
        printf("%d ",p->data);
    }
    printf("\n");
 }
 int main()
 {
     int m,n;
     PNODE headm;
     PNODE headn;
     while(~scanf("%d%d",&m,&n))
     {
         headm=build(m);
        headn=build(n);
        judge(headm,headn);
        PRINT(headm);
        PRINT(headn);
    }
 }

 

因为晚上选修课考试,八点三十回寝室才开始学习到十点半,一共做了两道题目

第一题题目如下:

1518: 最快合并链表(线性表)

时间限制:1s

内存限制:128MB


题目描述

知L1、L2分别为两循环单链表的头结点指针,m,n分别为L1、L2表中数据结点个数。要求设计一算法,用最快速度将两表合并成一个带头结点的循环单链表。

输入格式

m=5

3 6 1 3 5

n=4

7 10 8 4

输出格式

3 6 1 3 5 7 10 8 4

样例输入content_copy

m=7
3 5 1 3 4 6 0

n=5
5 4 8 9 5

样例输出content_copy

3 5 1 3 4 6 0 5 4 8 9 5 

结题思路:直接将第一个链表尾链接到第二个链表的第一个节点上就可以(此题因为两个getchar();的问题耗费了过多时间)

#include<bits/stdc++.h>
using namespace std;
#define New  (struct node*)malloc(sizeof(struct node))
typedef struct node
{
    int data;
    node *next;
}node;
int n,m;
node *creat(int num)
 {
     node* head=NULL;
     node* p1=head;
    node* p2=NULL;
    int data;
     for(int i=0;i<num;i++)
     {
         scanf("%d",&data);
         if(head==NULL){head=New;p1=head;head->data=data;}
         else{p2=New;p1->next=p2;p2->data=data;p1=p2;p1->next=NULL;}
    }
    p2=New;
    p2->next=head;
    head=p2;
    head->data=-1;
    return head;
 }
int main()
{
    int i;
    node *heada=NULL,*headb=NULL;
    scanf("m=%d",&m);
    heada=creat(m);//创建A链表
    getchar();
    getchar();//这两个getchar我真的是查了半个多小时bug才查不来的
    scanf("n=%d",&n);
    headb=creat(n);//创建B链表
    node *p1;
    p1=heada->next;
    while(p1->next)p1=p1->next;
    p1->next=headb->next;
    p1=heada->next;
    while(p1)
    {
        printf("%d ",p1->data);
        p1=p1->next;
    }
}

第二题题目如下:

题目描述

(线性表)已知不带头结点的线性链表list,链表中结点构造为(data、link),其中data为数据域,link为指针域。请写一算法,将该链表按结点数据域的值的大小从小到大重新链接。要求链接过程中不得使用除该链表以外的任何链结点空间。

输入格式

自定义链表节点数

m=5

3 1 5 4 6

输出格式

1 3 4 5 6

样例输入content_copy

8

10 1 5 14 32 55 67 6

样例输出content_copy

1 5 6 10 14 32 55 67 

解题思路:和其他排序题思路差不多,只是需要非常注意链表指针指向的问题。

#include<bits/stdc++.h>
using namespace std;
#define New  (struct node*)malloc(sizeof(struct node))
typedef struct node
{
    int data;
    node *next;
}node;
node *creat(int num)//使用尾插法创建链表
 {
     node* head=NULL,*p1=head,*p2=NULL;
    int data;
     for(int i=0;i<num;i++)
     {
         scanf("%d",&data);
         if(head==NULL){head=New;p1=head;head->data=data;}
         else{p2=New;p1->next=p2;p2->data=data;p1=p2;p1->next=NULL;}
    }
    return head;
 }
 node *sortlist(node *h)
{
    node *h1,*p,*q,*qm,*pm,*t;
    h1=NULL;
    while(h)
    {
        for(pm=q=h,p=h->next;p;q=p,p=p->next)//每次找出链表中的最大值,qm记下最大值的前一个,pm记下最大值
            if(p->data>pm->data)
            {
                qm=q;
                pm=p;
            }
        if(pm!=h)//若最大值不是第一个,就将最大值的节点从链表中分离出来
            qm->next=pm->next;
        else
            h=h->next;
        pm->next=h1;//每次找出来的最大值用头插法实现升序
        h1=pm;//h1始终指向升序链表的第一个节点
    }
    return h1;
}
void outlist(node *h)//输出链表
{
    while(h)
    {
        printf("%d ",h->data);
        h=h->next;
    }
}
 int main()
 {
     int m;
     scanf("%d",&m);
     node *head=creat(m);
     head=sortlist(head);
     outlist(head);
 }
通过今天的学习,我对于链表的操作稍微熟练了一点点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值