数据结构(李清云)实验三答案

已知带头结点的链表结构定义及头插法建表、尾插法建表和打印链表等函数定义如下(详见slnklist.h文件),基于该文件完成实验题1~实验题9.

#include <stdio.h>

#include <stdlib.h>

#define maxsize 100

typedef int datatype;

typedef struct link_node{

    datatype info;

    struct link_node *next;

}node;

typedef node *linklist;

/********************************************/

/*函数名称:creatbystack()                  */

/*函数功能:头插法建立单链表                */

/********************************************/

linklist creatbystack()

{

    linklist head,s;

    datatype x;

    head->next=NULL;

    printf("请输入若干整数序列:\n");

    scanf("%d",&x);

    while(x!=0)            /*以0结束输入*/

    {

        s=(linklist)malloc(sizeof(node));  /*生成待插入结点*/

        s->info=x;

        s->next=head->next;           /*将新结点插入到链表最前面*/

        head->next=s;

        scanf("%d",&x);

    }

    return head;        /*返回建立的单链表*/

}

/********************************************/

/*函数名称:creatbyqueue()                  */

/*函数功能:尾插法建立单链表                */

/********************************************/

linklist creatbyqueue()

{

linklist head,r,s;

head=(linklist)malloc(sizeof(node));

    datatype x;

    head->next=r=NULL;

    printf("请输入若干整数序列:/n");

    scanf("%d",&x);

    while(x!=0)              /*以0结束输入*/

    {

        s=(linklist)malloc(sizeof(node));

        s->info=x;

        if(head->next==NULL)       /*将新结点插入到链表最后面*/

            head->next=s;

        else r->next=s;

        r=s;

        scanf("%d",&x);

    }

    r->next=NULL;

    return head;           /*返回建立的单链表*/

}

/********************************************/

/*函数名称:print()                         */

/*函数功能:输入带头结点的单链表          */

/********************************************/

void print(linklist head)

{

    linklist p;

    int i=0;

    p=head->next;

    printf("List is:\n");

    while(p)

    {

        printf("%5d",p->info);

        p=p->next;

        i++;

        if(i%10==0)  printf("\n");

    }

    printf("\n");

}

/********************************************/

/*函数名称:delList()                       */

/*函数功能:释放带头结点的单链表                */

/********************************************/

void delList(linklist head)

{

    linklist p=head->next;

    while(p)

    {

        Head->next=p->next;

        free(p);

        p=head->next;

    }

}

(1)编写函数void delx(linklist head,datatype x),删除带头结点单链表head中的第一个值为x的结点,并构造测试用例进行测试(实验代码详见lab3_01.c)

#include <stdio.h>

#include <stdlib.h>

#define maxsize 100

typedef int datatype;

typedef struct link_node{

    datatype info;

    struct link_node *next;

}node;

typedef node *linklist;

linklist creatbyqueue()

{

    linklist head,r,s;

    datatype x;

    head->next=r=NULL;

    printf("请输入若干整数序列:\n");

    scanf("%d",&x);

    while(x!=0)

    {

        s=(linklist)malloc(sizeof(node));

        s->info=x;

        if(head->next==NULL)

            head->next=s;

        else r->next=s;

        r=s;

        scanf("%d",&x);

    }

    if(r) r->next=NULL;

    return head;

}

void print(linklist head)

{

    linklist p;

    int i=0;

    p=head->next;

    printf("List is:\n");

    while(p)

    {

        printf("%5d",p->info);

        p=p->next;

        i++;

        if(i%10==0)  printf("\n");

    }

    printf("\n");

}

void delList(linklist head)

{

    linklist p=head->next;

    while(p)

    {

        head->next=p->next;

        free(p);

        p=head->next;

    }

}

void delx(linklist head,datatype x)

{

    linklist p,pre;

    pre=head;p=head->next;

    while(p && p->info!=x)

    {

        pre=p;

        p=p->next;

    }

    if(p)

    {

        pre->next=p->next;

        free(p);

    }

}

int main()

{

    datatype x;

    linklist head;

    head=creatbyqueue();

    print(head);

    printf("请输入要删除的值:");

    scanf("%d",&x);

    delx(head,x);

    print(head);

    delList(head);

    return 0;

}

(2)假设线性表(a1,a2,a3,……,an)采用带头结点的单链表存储,请设计算法函数void reverse(linklist head)将带头结点的单链表head倒置,使表变成(an,an-1,……,a3,a2,a1).并构造测试用例进行测试(实验代码详见lab3_02.c)

#include <stdio.h>

#include <stdlib.h>

#define maxsize 100

typedef int datatype;

typedef struct link_node{

    datatype info;

    struct link_node *next;

}node;

typedef node *linklist;

linklist creatbystack()

{

    linklist head,s;

    datatype x;

    head->next=NULL;

    printf("请输入若干整数序列:\n");

    scanf("%d",&x);

    while(x!=0)

    {

        s=(linklist)malloc(sizeof(node));

        s->info=x;

        s->next=head->next;

        head->next=s;

        scanf("%d",&x);

    }

    return head;

}

void print(linklist head)

{

    linklist p;

    int i=0;

    p=head->next;

    printf("List is:\n");

    while(p)

    {

        printf("%5d",p->info);

        p=p->next;

        i++;

        if(i%10==0)  printf("\n");

    }

    printf("\n");

}

void delList(linklist head)

{

    linklist p=head->next;

    while(p)

    {

        head->next=p->next;

        free(p);

        p=head->next;

    }

}

void reverse(linklist head)

{

    linklist p,q;

    p=head->next;

    q=head->next->next;

    while(q!=NULL)

    {

        p->next=q->next;

        q->next=head->next;

        head->next=q;

        q=p->next;

    }

}

int main()

{

    datatype x;

    linklist head;

    head=creatbystack();

    print(head);

    reverse(head);

    print(head);

    delList(head);

    return 0;

}

(3)假设带头结点的单链表head是升序排列的,设计算法函数void insert(linklist head,datatype x),将值为x的结点插入到链表head中,并保持链表的有序性。分别构造插入到表头、表中、表尾3种情况的测试样例进行测试。(实验代码详见lab3_03.c)

#include <stdio.h>

#include <stdlib.h>

#define maxsize 100

typedef int datatype;

typedef struct link_node{

    datatype info;

    struct link_node *next;

}node;

typedef node *linklist;

linklist creatbyqueue()

{

    linklist head,r,s;

    datatype x;

    head->next=r=NULL;

    printf("请输入若干整数序列:\n");

    scanf("%d",&x);

    while(x!=0)

    {

        s=(linklist)malloc(sizeof(node));

        s->info=x;

        if(head->next==NULL)

            head->next=s;

        else r->next=s;

        r=s;

        scanf("%d",&x);

    }

    if(r) r->next=NULL;

    return head;

}

void print(linklist head)

{

    linklist p;

    int i=0;

    p=head->next;

    printf("List is:\n");

    while(p)

    {

        printf("%5d",p->info);

        p=p->next;

        i++;

        if(i%10==0)  printf("\n");

    }

    printf("\n");

}

void delList(linklist head)

{

    linklist p=head->next;

    while(p)

    {

        head->next=p->next;

        free(p);

        p=head->next;

    }

}

void insert(linklist head,datatype x)

{

    linklist p,pre,s,r;

    pre=head;

    p=head->next;

    s=(linklist)malloc(sizeof(node));

    s->info=x;

    s->next=NULL;

    while(p && p->info<x)

    {

        pre=p;

        p=p->next;

    }

    if(p)

    {

        if(!pre)

        {

            s->next=p;

            head->next=s;

        }

        else

        {

            s->next=p;

            pre->next=s;

        }

    }

    else

    {

        pre->next=s;

    }

}

int main()

{

    datatype x;

    linklist head;

    printf("请输入一组升序排列的整数:\n");

    head=creatbyqueue();

    print(head);

    printf("请输入要插入的值:");

    scanf("%d",&x);

    insert(head,x);

    print(head);

    delList(head);

    return 0;

}

(4)编写算法函数void linklist delallx(linklist head,int x),删除带头结点单链表head中所有值为x的结点。

#include <stdio.h>

#include <stdlib.h>

#define maxsize 100

typedef int datatype;

typedef struct link_node{

    datatype info;

    struct link_node *next;

}node;

typedef node *linklist;

linklist creatbyqueue()

{

    linklist head,r,s;

    datatype x;

    head->next=r=NULL;

    printf("请输入若干整数序列:\n");

    scanf("%d",&x);

    while(x!=0)

    {

        s=(linklist)malloc(sizeof(node));

        s->info=x;

        if(head->next==NULL)

            head->next=s;

        else r->next=s;

        r=s;

        scanf("%d",&x);

    }

    if(r) r->next=NULL;

    return head;

}

void print(linklist head)

{

    linklist p;

    int i=0;

    p=head->next;

    printf("List is:\n");

    while(p)

    {

        printf("%5d",p->info);

        p=p->next;

        i++;

        if(i%10==0)  printf("\n");

    }

    printf("\n");

}

void delList(linklist head)

{

    linklist p=head->next;

    while(p)

    {

        head->next=p->next;

        free(p);

        p=head->next;

    }

}

void linklist_delallx(linklist head,int x)

{

    linklist p,pre;

    p=head->next;

    pre=head;

    while(p)

    {

        if(p->info==x&&!pre)

        {

            head->next=p->next;

            pre=head;

            p=p->next;

        }

        else if(p->info==x&&pre)

        {

            pre->next=p->next;

            p=p->next;

        }

        else

        {

            pre=p;

            p=p->next;

        }

    }

}

int main()

{

    datatype x;

    linklist head;

    head=creatbyqueue();

    print(head);

    printf("请输入要删除的值:");

    scanf("%d",&x);

    linklist_delallx(head,x);

    print(head);

    delList(head);

    return 0;

}

(5)已知线性表存储在带头结点的单链表head中,请设计算法函数void sort(linklist head),将head中的结点按结点值升序排列。(实验代码详见lab3_05.c)

#include <stdio.h>

#include <stdlib.h>

#define maxsize 100

typedef int datatype;

typedef struct link_node{

    datatype info;

    struct link_node *next;

}node;

typedef node *linklist;

linklist creatbyqueue()

{

    linklist head,r,s;

    datatype x;

    head->next=r=NULL;

    printf("请输入若干整数序列:\n");

    scanf("%d",&x);

    while(x!=0)

    {

        s=(linklist)malloc(sizeof(node));

        s->info=x;

        if(head->next==NULL)

            head->next=s;

        else r->next=s;

        r=s;

        scanf("%d",&x);

    }

    if(r) r->next=NULL;

    return head;

}

void print(linklist head)

{

    linklist p;

    int i=0;

    p=head->next;

    printf("List is:\n");

    while(p)

    {

        printf("%5d",p->info);

        p=p->next;

        i++;

        if(i%10==0)  printf("\n");

    }

    printf("\n");

}

void delList(linklist head)

{

    linklist p=head->next;

    while(p)

    {

        head->next=p->next;

        free(p);

        p=head->next;

    }

}

void sort(linklist head)

{

    linklist p,q,n,r;//n的作用是每次冒泡排序后指向最后一个数(找出最大值)的前一个数,效果是下一次的冒泡排序次数减少一次,提高了代码效率

    n=NULL;

    r=head;

    while(r->next!=n)//单链表不为空

    {

        p=head;

        q=p->next;

        while(q->next!=n)

        {

            if(q->info > q->next->info)

            {

                p->next=q->next;

                q->next=q->next->next;

                p->next->next=q;

                p=p->next;

            }

            else

            {

                p=p->next;

                q=q->next;

            }

        }

        n=q;

    }

}

int main()

{

    linklist head;

    head=creatbyqueue();

    print(head);

    sort(head);

    print(head);

    delList(head);

    return 0;

}

(6)已知两个带头结点的单链表L1和L2中的结点值均已按升序排序。设计算法函数linklist mergeAscend (linklist L1,linklist L2)将L1和L2合并成一个升序的带头结点的单链表作为函数的返回值;设计算法函数linklist mergeDesend(linklist L1,linklist L2)将L1和L2合并成一个降序的带头结点的单链表作为函数的返回结果;并设计main()函数进行测试。(要求利用原链表中的结点,不需复制新结点)(实验代码详见lab3_06.c)

#include <stdio.h>

#include <stdlib.h>

#define maxsize 100

typedef int datatype;

typedef struct link_node{

    datatype info;

    struct link_node *next;

}node;

typedef node *linklist;

linklist creatbyqueue()

{

    linklist head,r,s;

    datatype x;

    head=(linklist)malloc(sizeof(node));

    head->next=r=NULL;

    printf("请输入若干整数序列:\n");

    scanf("%d",&x);

    while(x!=0)

    {

        s=(linklist)malloc(sizeof(node));

        s->info=x;

        if(head->next==NULL)

            head->next=s;

        else r->next=s;

        r=s;

        scanf("%d",&x);

    }

    if(r) r->next=NULL;

    return head;

}

void print(linklist head)

{

    linklist p;

    int i=0;

    p=head->next;

    printf("List is:\n");

    while(p)

    {

        printf("%5d",p->info);

        p=p->next;

        i++;

        if(i%10==0)  printf("\n");

    }

    printf("\n");

}

void delList(linklist head)

{

    linklist p=head->next;

    while(p)

    {

        head->next=p->next;

        free(p);

        p=head->next;

    }

}

/*linklist mergeAscend(linklist L1,linklist L2)

{

    linklist head,p,q;

    p=L1->next;

    q=L2->next;

    head=(linklist)malloc(sizeof(node));

    linklist r=head;

    while(p&&q)

    {

        if(p->info<=q->info)

        {

            r->next=p;

            p=p->next;

            r=r->next;

        }

        else

        {

            r->next=q;

            q=q->next;

            r=r->next;

        }

    }

    if(p==NULL)

        r->next=q;

    else

        r->next=p;

    return head;

}*/

linklist mergeDesend(linklist L1,linklist L2)

{

    linklist p1,p2,p1next,p2next,head;

    head=L1;

    p1=L1->next;

    p2=L2->next;

    head->next=NULL;

    free(L2);

    while(p1&&p2)

    {

        if(p1->info<=p2->info)

        {

            p1next=p1->next;

            p1->next=head->next;

            head->next=p1;

            p1=p1next;

        }

        else

        {

            p2next=p2->next;

            p2->next=head->next;

            head->next=p2;

            p2=p2next;

        }

    }

    while(p1)

    {

        p1next=p1->next;

        p1->next=head->next;

        head->next=p1;

        p1=p1next;

    }

    while(p2)

    {

        p2next=p2->next;

        p2->next=head->next;

        head->next=p2;

        p2=p2next;

    }

    return head;

}

int main()

{

    linklist h1,h2,h3;

    h1=creatbyqueue();

    h2=creatbyqueue();

    print(h1);

    print(h2);

    /*h3=mergeAscend(h1,h2);

    print(h3);*/

    h3=mergeDesend(h1,h2);

    print(h3);

    delList(h3);

    return 0;

}

(7)设计一个算法linklist interSection(linklist L1,linklist L2),求两个单链表表示的集合L1和L2的交集,并将结果用一个新的带头结点的单链表保存并返回表头地址。(实验代码详见lab3_07.c)

#include <stdio.h>

#include <stdlib.h>

#define maxsize 100

typedef int datatype;

typedef struct link_node{

    datatype info;

    struct link_node *next;

}node;    

typedef node *linklist;

linklist creatbyqueue()

{

    linklist head,r,s;

    head=(linklist)malloc(sizeof(node));

    datatype x;

    head->next=r=NULL;

    printf("请输入若干整数序列:\n");

    scanf("%d",&x);

    while(x!=0)

    {

        s=(linklist)malloc(sizeof(node));

        s->info=x;

        if(head->next==NULL)

            head->next=s;

        else r->next=s;

        r=s;

        scanf("%d",&x);

    }

    r->next=NULL;

    return head;

}

void print(linklist head)

{

    linklist p;

    int i=0;

    p=head->next;

    printf("List is:\n");

    while(p)

    {

        printf("%5d",p->info);

        p=p->next;

        i++;

        if(i%10==0)  printf("\n");

    }

    printf("\n");

}

void delList(linklist head)

{

    linklist p=head->next;

    while(p)

    {

        head->next=p->next;

        free(p);

        p=head->next;

    }

}

linklist interSection(linklist L1,linklist L2)

{

    linklist head,p1,p2,s,r;

    p1=L1->next;

    p2=L2->next;

    head=(linklist)malloc(sizeof(node));

    head->next=NULL;

    r=head;

    while(p1)

    {

        while(p2)

        {

            if(p1->info==p2->info)

            {

                s=(linklist)malloc(sizeof(node));

                s->info=p1->info;

                r->next=s;

                r=r->next;

            }

            p2=p2->next;

        }

        p1=p1->next;

        p2=L2->next;

    }

    r->next=NULL;

    return head;

}

int main()

{

    linklist h1,h2,h3;

    h1=creatbyqueue();

    h2=creatbyqueue();

    print(h1);

    print(h2);

    h3=interSection(h1,h2);

    print(h3);

    delList(h1);

    delList(h2);

    delList(h3);

    return 0;

}

(8)请编写一个算法函数void partion(linklist head),将带头结点的单链表head中的所有值为奇数的结点调整到链表的前面,所有值为偶数的结点调整到链表的后面。(实验代码详见lab3_08.c)

#include <stdio.h>

#include <stdlib.h>

#define maxsize 100

typedef int datatype;

typedef struct link_node{

    datatype info;

    struct link_node *next;

}node;

typedef node *linklist;

linklist creatbyqueue()

{

    linklist head,r,s;

    datatype x;

    head->next=r=NULL;

    printf("请输入若干整数序列:\n");

    scanf("%d",&x);

    while(x!=0)

    {

        s=(linklist)malloc(sizeof(node));

        s->info=x;

        if(head->next==NULL)

            head->next=s;

        else r->next=s;

        r=s;

        scanf("%d",&x);

    }

    if(r) r->next=NULL;

    return head;

}

void print(linklist head)

{

    linklist p;

    int i=0;

    p=head->next;

    printf("List is:\n");

    while(p)

    {

        printf("%5d",p->info);

        p=p->next;

        i++;

        if(i%10==0)  printf("\n");

    }

    printf("\n");

}

void delList(linklist head)

{

    linklist p=head->next;

    while(p)

    {

        head->next=p->next;

        free(p);

        p=head->next;

    }

}

void partion(linklist head)

{

    linklist p,q;

    q=head->next;

    p=head->next->next;

    while(p)

    {

        if(p->info%2)

        {

            q->next=p->next;

            p->next=head->next;

            head->next=p;

            p=q->next;

        }

        else

        {

            q=p;

            p=p->next;

        }

    }

}

int main()

{

    linklist head;

    head=creatbyqueue();

    print(head);

    partion(head);

    print(head);

    delList(head);

    return 0;

}

(9)编写一个程序,用尽可能快的方法返回带头结点单链表中倒数第k个结点的值,如果不存在,则返回NULL。(实验代码详见lab3_09.c)

#include <stdio.h>

#include <stdlib.h>

#define maxsize 100

typedef int datatype;

typedef struct link_node{

    datatype info;

    struct link_node *next;

}node;

typedef node *linklist;

linklist creatbyqueue()

{

    linklist head,r,s;

    datatype x;

    head->next=r=NULL;

    printf("请输入若干整数序列:\n");

    scanf("%d",&x);

    while(x!=0)

    {

        s=(linklist)malloc(sizeof(node));

        s->info=x;

        if(head->next==NULL)

            head->next=s;

        else r->next=s;

        r=s;

        scanf("%d",&x);

    }

    if(r) r->next=NULL;

    return head;

}

void print(linklist head)

{

    linklist p;

    int i=0;

    p=head->next;

    printf("List is:\n");

    while(p)

    {

        printf("%5d",p->info);

        p=p->next;

        i++;

        if(i%10==0)  printf("\n");

    }

    printf("\n");

}

void delList(linklist head)

{

    linklist p=head->next;

    while(p)

    {

        head->next=p->next;

        free(p);

        p=head->next;

    }

}

linklist search(linklist head,int k)

{

    linklist p,r;

    int length=0;

    int j=0;

    r=head;

    while(r)

    {

        r=r->next;

        length++;

    }

    p=head;

    while(p && j!=length-k)

    {

        p=p->next;

        j++;

    }

    if(!p)

        return NULL;

    else

        return p;

}

int main()

{

    int k;

    linklist head,p;

    head=creatbyqueue();

    print(head);

    printf("k=");

    scanf("%d",&k);

    p=search(head,k);

    if(p) printf("%d\n",p->info);

    else

        printf("Not Found!\n");

    delList(head);

    return 0;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值