【无标题】1月10日学习总结---单向链表的排序、插入和删除

今天白天学会了链表的排序(选择和冒泡)、合并、插入、删除

链表的合并

题目描述

知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
3 5 1 3 4 6 0 5 4 8 9 5 

样例输出content_copy

#include<stdio.h>
#include<string.h>
struct note//定义结构体类型
{
    int date;
    struct note *next;
};
int n,m;//全局变量
struct note *creat (int n)//创建链表
{
    struct note *p,*q,*head,*t;
    int a,i;
    head=NULL;
    for(i=0; i<n; i++)
    {
        scanf("%d",&a);
        p=(struct note *)malloc(sizeof(struct note));
        p->date=a;
        p->next=NULL;
        if(head==NULL)
            head=p;
        else
            q->next=p;
        q=p;
    }
    return head;
};
int main()
{
    struct note *t,*p,*l;
    scanf("m=%d",&m);
    t=creat(m);
    getchar();
    getchar();//回收字符串(很有必要,因为在例题中输入的两组数据中间有一个空行)
    l=t;
    scanf("n=%d",&n);
    p=creat(n);
    while(t!=NULL)
    {
        if(t->next==NULL)
        {
            t->next=p;//将t链表末尾指向空的指针指向p的首地址
            break;
        }
        t=t->next;
    }
    while(l!=NULL)
    {
        printf("%d ",l->date);
        l=l->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<stdio.h>
#include<string.h>
struct note
{
    int date;
    struct note *next;
};
int main()
{
    struct note *p,*q,*head,*t,*b;
    int a,i,n;
    scanf("%d",&n);
    head=NULL;
    for(i=0; i<n; i++)
    {
        scanf("%d",&a);
        p=(struct note *)malloc(sizeof(struct note));
        p->date=a;
        p->next=NULL;
        if(head==NULL)
            head=p;
        else
            q->next=p;
        q=p;
    }
    b=head;
    t=head;
    int k;
    while(b->next!=NULL)
    {
        t=b->next;//t指针始终表示b所指向的下一个地址
        while(t!=NULL)
        {
            if(b->date>t->date)//比较前后两个地址的数据大小
            {
                k=b->date;
                b->date=t->date;
                t->date=k;
            }//交换两个地址的数值
            t=t->next;
        }
        b=b->next;
    }
    t=head;
    while(t!=NULL)
    {
        printf("%d ",t->date);
        t=t->next;
    }
}
冒泡排序

#include<stdio.h>
#include<string.h>
struct note
{
    int date;
    struct note *next;
};
int main()
{
    struct note *p,*q,*head,*t,*tail;
    int a,i,n;
    scanf("%d",&n);
    head=NULL;
    for(i=0; i<n; i++)
    {
        scanf("%d",&a);
        p=(struct note *)malloc(sizeof(struct note));
        p->date=a;
        p->next=NULL;
        if(head==NULL)
            head=p;
        else
            q->next=p;
        q=p;
    }
    t=head;
    tail=NULL;
    int k;
    while(t->next!=tail)
    {
        while(t->next!=tail)
        {
            if(t->date>t->next->date)
            {
                k=t->date;
                t->date=t->next->date;
                t->next->date=k;
            }//将最大的数移到最后
            t=t->next;
        }
        tail=t;//将链表的尾指针前移
        t=head;//将t指针重新定义为头指针,从头再次遍历
    }
    t=head;
    while(t!=NULL)
    {
        printf("%d ",t->date);
        t=t->next;
    }
}

 插入

题目描述

(线性表)已知一单链表,从第二个结点至表尾递增有序,(设a1<x<an)如下图(“第二个结点至表尾”指a1..an )。试编写程序,将第一个结点删除并插入表中适当位置,使整个链表递增有序。

输入格式

输入长度n:7

输入数据:4 1 2 3 6 8 9

输出格式

1 2 3 4 6 8 9

样例输入content_copy

5
11 7 8 9 10

样例输出content_copy

7 8 9 10 11 

 

#include<stdio.h>
#include<string.h>
struct note
{
    int date;
    struct note *next;
};
int main()
{
    struct note *p,*q,*head,*t;
    int a,i,n;
    scanf("%d",&n);
    head=NULL;
    for(i=0;i<n;i++)
    {
        scanf("%d",&a);
        p=(struct note *)malloc(sizeof(struct note));
        p->date=a;
        p->next=NULL;
        if(head==NULL)
            head=p;
        else
            q->next=p;
        q=p;
    }
    int k,leap=0;
    k=head->date;
    t=head;
    while(t->next!=NULL)
    {
       if(k<t->next->date)
       {
            p=(struct note *)malloc(sizeof(struct note));
            p->date=k;
            p->next=t->next;
            t->next=p;
            leap=1;
            break;
       }
        t=t->next;
    }
    if(leap==0)
    {
        t=head;
        for(;;)
        {
            t=t->next;
            if(t->next==NULL)
            {

                p=(struct note *)malloc(sizeof(struct note));
                p->date=k;
                p->next=NULL;
                t->next=p;
                break;
            }
        }
    }
    t=head->next;
    while(t!=NULL)
    {
        printf("%d ",t->date);
        t=t->next;
    }
}

 

删除

题目描述

已知非空线性链表由list指出,链结点的构造为(data,link).请写一算法,将链表中数据域值最小的那个链结点移到链表的最前面。要求:不得额外申请新的链结点

输入格式

输入长度n:6

 输入数据:4 2 6 88 34 6

输出格式

2 4 6 88 34 6

样例输入content_copy

5
11 6 8 7 9

样例输出content_copy

6 11 8 7 9 

 

#include<stdio.h>
#include<string.h>
struct note
{
    int date;
    struct note *next;
};
int main()
{
    struct note *p,*q,*head,*t,*b;
    int a,i,n;
    scanf("%d",&n);
    head=NULL;
    for(i=0;i<n;i++)
    {
        scanf("%d",&a);
        p=(struct note *)malloc(sizeof(struct note));
        p->date=a;
        p->next=NULL;
        if(head==NULL)
            head=p;
        else
            q->next=p;
        q=p;
    }
    t=head;
    int min=t->date;
    while(t->next!=NULL)
    {
        if(min>t->next->date)
            min=t->next->date;
        t=t->next;
    }
    t=head;
    while(t!=NULL)
    {
        if(t->next->date==min)
        {
            b=t->next;//将b指针指向t的后一个地址
            t->next=t->next->next;//将t指针指向t指针的下下个地址,达到删除t指针的后一个地址的目的
            b->next=head;//同时将删去的b指针指向t链表的头指针
            break;
        }
    }
    t=b;
    //printf("%d %d %d\n",b->date,b->next->date,head->date);
    while(t!=NULL)
    {
        printf("%d ",t->date);
        t=t->next;
    }
}

今天学习了链表,完成了链表的6道题,还听学长讲了dfs,bfs,和快排

明日计划

 学习链表的双向循环,继续完成链表的其他题目

学习搜索,写洛谷上的题目

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值