数据结构——链表(一)(2022考研)

链表——单链表

#include<stdlib.h>
#include<stdio.h>

#define Elemtype int

typedef struct LNode{
  Elemtype data;
  struct LNode *next;
}LNode,*LinkList;

void InitLink(LinkList &L)
{
    L= (LNode*)malloc(sizeof (LNode));
    L->next=NULL;
}

bool Empty(LinkList L)
{
    if(L->next==NULL)
        return true;
    else
        return false;
}

LNode * GetElem(LinkList L,int i)
{
    int j=0;
    LNode *p=L;
    while(p!=NULL && j<i)
    {
        p=p->next;
        j++;
    }
    return p;
}

void InsertLink(LinkList &L,int i,Elemtype e)
{
    LNode *q= (LNode*)malloc(sizeof(LNode));
    q->data=e;
    LNode *p = GetElem(L,i-1);
    q->next=p->next;
    p->next=q;
}

void DeleteLink(LinkList &L,int i)
{
    LNode *p= GetElem(L,i-1);
    LNode *q=p->next;
    p->next=q->next;
    free(q);
}

void Length(LinkList L,int &s)
{
    int i=0;
    LNode *p=L;
    while(p!=NULL)
    {
        p=p->next;
        i++;
    }
    s=i-1;
}

void PrintLink(LinkList L)
{
    LNode *p=L->next;
    while(p!=NULL)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
}

以上是单链表的基操代码实现

以下是针对《2022年数据结构考研复习指导》课后复习题的训练内容

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

//习题2.1---递归删除无头结点所有x值结点
void DeleteCommon1(LinkList &L,Elemtype e)
{
    LNode *p;
    if(L==NULL)
        return;
    if(L->data==e)
    {
        p=L;
        L=L->next;
        free(p);
        DeleteCommon1(L,e);
    }
    else
        DeleteCommon1(L->next,e);
}

//习题2.2(1)---前结点删除所有x值
void DeleteCommon2(LinkList &L,Elemtype e)
{
    LNode *p=L->next,*pre=L,*q;
    while(p!=NULL)
    {
        if(p->data==e)
        {
            q=p;
            p=p->next;
            pre->next=p;
            free(q);
        }
        else{
            pre=p;
            p=p->next;
        }
    }
}

//习题2.2(2)---尾结点删除所有x值
void DeleteCommon3(LinkList &L,Elemtype e)
{
    LNode *p=L->next,*r=L,*q;
    while(p!=NULL)
    {
        if(p->data!=e)
        {
            r->next=p;
            r=p;
            p=p->next;
        }
        if(p->data==e)
        {
            q=p;
            p=p->next;
            free(q);
        }
    }
    r->next=NULL;
}

//习题2.3---递归法逆置输出
void ReversePrint(LinkList L)
{
    if(L!=NULL){
        ReversePrint(L->next);
        printf("%d ",L->data);
    }
    if(L==NULL){
        return;
    }
}

//习题2.4---删除最小值
void DeleteMin(LinkList &L)
{
    LNode *p=L->next,*pre=L,*q;
    int t=p->data;
    while(p!=NULL)
    {
        if(t>p->data)
        {
            q=pre;
            t=p->data;
        }
        pre=p;
        p=p->next;
    }
    LNode *k=q->next;
    q->next=k->next;
    free(k);
}

//习题2.5(1)---头插法逆置
void Reverse1(LinkList &L)
{
    LNode *p=L->next->next,*r=L->next,*q;
    while(p!=NULL)
    {
        q=p->next;
        p->next=L->next;
        L->next=p;
        p=q;
    }
    r->next=NULL;
}

//习题2.5(2)---逆置箭头逆置
void Reverse2(LinkList &L)
{
    LNode *pre,*p=L->next,*t=p->next;
    p->next=NULL;
    while(t!=NULL)
    {
        pre=p;
        p=t;
        t=t->next;
        p->next=pre;
    }
    L->next=p;
}

//习题2.6---递增有序
void Sort(LinkList &L)
{
    LNode *pre,*p=L->next,*r=p->next;
    p->next=NULL;
    p=r;
    while(p!=NULL)
    {
        pre=L;
        r=p->next;
        while(pre->next!=NULL && pre->next->data<p->data)
        {
            pre=pre->next;
        }
        p->next=pre->next;
        pre->next=p;
        p=r;
    }
}

//习题2.7---删除一个阈值内的值
void DeleteMid(LinkList &L,Elemtype s,Elemtype t)
{
    LNode *pre=L,*p=L->next,*q;
    while(p!=NULL)
    {
        if(p->data>=s && p->data<=t)
        {
            q=p;
            p=p->next;
            pre->next=p;
            free(q);
        }
        else{
            p=p->next;
            pre=pre->next;
        }
    }
}

//习题2.8---寻找公共结点
LNode * SearchNode(LinkList L1,LinkList L2)
{
    LinkList shortList,longList;
    int i,j,dist;
    Length(L1,i);
    Length(L2,j);
    if(i>=j)
    {
        shortList=L2;
        longList=L1;
        dist=i-j;
    }
    else{
        shortList=L1;
        longList=L2;
        dist=j-i;
    }
    while(dist)
        longList=longList->next;
    while(longList!=NULL)
    {
        if(longList==shortList)
            return longList;
        else{
            longList=longList->next;
            shortList=shortList->next;
        }
    }
    return NULL;

}

//习题2.9---递增输出
void PrintMin(LinkList &L)
{
    while(L->next!=NULL)
    {
        int t=L->next->data;
        LNode *pre=L,*p=L->next,*q;
        while(p!=NULL)
        {
            if(p->data<=t)
            {
                t=p->data;
                q=pre;
            }
            pre=pre->next;
            p=p->next;
        }
        printf("%d ",q->next->data);
        LNode *k=q->next;
        q->next=k->next;
        free(k);
    }
    free(L);
}

//习题2.10---分解为奇偶两个链表
void Decompose(LinkList &A,LinkList &B)
{
    LNode *a=A,*b=B,*p=A->next;
    while(p!=NULL)
    {
        if(p->data%2==0)
        {
            b->next=p;
            b=b->next;
        }
        if(p->data%2==1)
        {
            a->next=p;
            a=a->next;
        }
        p=p->next;
    }
    a->next=NULL;
    b->next=NULL;
}

//习题2.11---分解为两个链表,并顺序和倒置
void Decompose_X(LinkList C,LinkList &A,LinkList &B)
{
    int i=1;
    LNode *a=A,*b=B,*p=C->next,*r;
    b->next=NULL;
    while(p!=NULL)
    {
        r=p->next;
        if(i%2==0)
        {
            p->next=b->next;
            b->next=p;
        }
        if(i%2==1)
        {
            a->next=p;
            a=a->next;
        }
        p=r;
        i++;
    }
    a->next=NULL;
}

//习题2.12---删除有序表的重复值
void DeleteRepeat(LinkList &L)
{
    LNode *pre=L->next,*p=pre->next,*q;
    while(p!=NULL)
    {
        if(pre->data==p->data)
        {
            q=p;
            p=p->next;
            pre->next=p;
            free(q);
        }
        pre=pre->next;
        p=p->next;
    }
}

//习题2.13---合并两个递增链表为一个递减链表
void Combine(LinkList &A,LinkList &B)
{
    LNode *a=A->next,*b=B->next,*ra=a->next,*rb=b->next;
    A->next=NULL;
    while(ra!=NULL && rb!=NULL)
    {
        if(a->data <= b->data)
        {
            ra=a->next;
            a->next=A->next;
            A->next=a;
            a=ra;
        }
        if(b->data <= a->data)
        {
            rb=b->next;
            b->next=A->next;
            A->next=b;
            b=rb;
        }
    }
    while(ra!=NULL)
    {
        ra=a->next;
        a->next=A->next;
        A->next=a;
        a=ra;
    }
    while(rb!=NULL)
    {
        rb=b->next;
        b->next=A->next;
        A->next=b;
        b=rb;
    }
    free(B);
}

//习题2.14---提取两个递增链表的公共元素,形成新链表
void ExtractCommon(LinkList  &C,LinkList A,LinkList B)
{
    LNode *a=A->next,*b=B->next,*ra=a->next,*rb=b->next;
    while(ra!=NULL && rb!=NULL)
    {
        if(a->data < b->data)
        {
            a=a->next;
            ra=a->next;
        }
        if(a->data > b->data)
        {
            b=b->next;
            rb=b->next;
        }
        if(a->data == b->data)
        {
            ra=a->next;
            rb=b->next;
            LNode *p=(LNode *) malloc(sizeof (LNode));
            p->data=a->data;
            p->next=C->next;
            C->next=p;
            a=ra;
            b=rb;
        }
    }
}

//习题2.15---取交集,并存与原链表
void Intersection(LinkList &A,LinkList &B)
{
    LNode *a=A->next,*b=B->next,*ra=a->next,*rb=b->next;
    A->next=NULL;
    while(ra!=NULL && rb!=NULL)
    {
        if(a->data < b->data)
        {
            a=a->next;
            ra=a->next;
        }
        if(a->data > b->data)
        {
            b=b->next;
            rb=b->next;
        }
        if(a->data == b->data)
        {
            ra=a->next;
            rb=b->next;
            a->next=A->next;
            A->next=a;
            a=ra;
            b=rb;
        }
    }
}

//习题2.16---判断是否是子序列
void JudgeSubsequence(LinkList &A,LinkList &B)
{
    LNode *a=A,*q=a,*b=B;
    while(b && a)
    {
        if(a->data == b->data)
        {
            a=a->next;
            b=b->next;
        }
        else{
            q=q->next;
            a=q;
            b=B;
        }
    }
    if(b==NULL)
        printf("B是A的子序列");
    else
        printf("B不是A的子序列");
}

//习题2.21---查找倒数第k值
void FindKey(LinkList &L,int k)
{
    LNode *p=L->next,*q=L->next;
    for(int i=k;i>0;i--)
    {
        p=p->next;
        if(p==NULL)
            printf("k值输入错误");
    }
    while(p!=NULL)
    {
        q=q->next;
        p=p->next;
    }
    printf("倒数%d的值为%d",k,q->data);
}

//习题2.22---参考习题2.8

//习题2.23---删除绝对值相同的值
void DeleteABS(LinkList &L,int n)
{
    LNode *pre=L,*p=pre->next;
    int s[n];
    for(int i=0;i<n+1;i++)
    {
        s[i]=0;
    }
    while(p!=NULL)
    {
        if(s[abs(p->data)]==0)
        {
            s[abs(p->data)]=1;
            pre=p;
            p=p->next;

        }
        if(s[abs(p->data)]==1)
        {
            LNode *q=p;
            p=p->next;
            pre->next=p;
            free(q);
        }
    }
    free(s);
}

//习题2.24---寻找环入口
LNode * JudgeCircle(LinkList &L)
{
    LNode * fast=L,* slow=L;
    while(slow!=NULL && fast->next!=NULL)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
            break;
    }
    LNode *p1=L,*p2=slow;
    while(p1!=p2){
        p1=p1->next;
        p2=p2->next;
    }
    return p1;
}

//习题2.25---将后半链表逆置并插入
void ReSort(LinkList &L)
{
    LNode *p1=L,*p2=L,*r,*p;
    while(p2!=NULL)
    {
        p1=p1->next;
        p2=p2->next;
        if(p2!=NULL)
            p2=p2->next;
    }
    p2=p1->next;
    p1->next=NULL;
    while(p2!=NULL)
    {
        r=p2->next;
        p2->next=p1->next;
        p1->next=p2;
        p2=r;
    }
    p=L->next;
    p2=p1->next;
    p1->next=NULL;
    while(p2!=NULL)
    {
        r=p2->next;
        p2->next=p->next;
        p->next=p2;
        p=p2->next;
        p2=r;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值