吉林大学超星MOOC高级语言程序设计 实验09(2022级)

目录

1. (程序题)创建单链表

2. (程序题)删除单链表重复节点

3. (程序题)求单链表中间结点

4. (程序题)单链表交换两节点

5. (程序题)单链表存储法雷序列

6. (程序题)合并单链表

7. (程序题)排序单链表


1. (程序题)

题目编号:Exp09-Basic01

题目名称:创建单链表

题目描述:请填写缺失代码完成程序,实现如下功能:

根据从键盘随机输入以0结束的若干非零整数,建立一个单链表;之后将此链表中保存的数字顺次输出,相邻数字间以一个西文空格间隔,最后一个数字后无任何字符;若是空链表,则输出NULL。

例如, 

输入:5 4 2 1 3 0 

输出:5 4 2 1 3

输入:0 5 4 2 1 3 0 

输出:NULL

#include <stdio.h>
#include <malloc.h>
struct cell { //单链表结点结构体定义
    int x;
    struct cell* next;
};
struct cell* build(void) { //新建单链表,并将建好的单链表首结点地址返回
    struct cell* head, * tmp, * p;
    head = tmp = p = NULL;
    int n;
    scanf("%d", &n);
    if (n == 0)
        return NULL;
    head = (struct cell*)malloc(sizeof(struct cell));
    head->x = n;
    scanf("%d", &n);
    p = head;
    while (n != 0) {
        tmp=(struct cell*)malloc(sizeof(struct cell));
        tmp->x = n;
        p->next = tmp;
        p = tmp;
        p->next = NULL;
        scanf("%d", &n);
    }
    return head;//返回单链表头
}


void print(struct cell* head) {//打印整个单链表,head是指向单链表首结点的指针
    struct cell* p;
    p = head;
    printf("%d", p->x);
    p = p->next;
    while (p != NULL) {
        printf(" %d", p->x);
        p = p->next;
    }
}
void release(struct cell* head) {//释放单链表空间,head是指向单链表首结点的指针
    struct cell* p;
    while(head!=NULL){
        p = head;
        head = p->next;
        free(p);
    }

}
int main(void) {
    struct cell* head;
    head = build();
    if (head != NULL)
        print(head);
    else
        printf("NULL");
    release(head);
}

2. (程序题)

题目编号:Exp09-Basic02,GJBook3-13-06

题目名称:删除单链表重复结点

题目描述:请填写缺失代码完成程序,实现如下功能:

首先根据键盘随机输入,以0结束的若干非零整数建立单链表;然后删除此链表中值重复的结点仅保留一个,且不改变原有结点顺序;最后将删除后链表中各结点值输出,相邻数字间以一个西文空格间隔,最后一个数字后无任何字符;若是空链表,则输出NULL。

例如,

输入:5 4 2 1 3 0 输出:5 4 2 1 3

输入: 4 2 1 3 3 2 0 输出:4 2 1 3

输入: 0 4 2 3 2 0 输出:NULL

#include <stdio.h>
#include <malloc.h>
struct cell {//单链表结点结构体定义
    int x;
    struct cell* next;
};
struct cell* build(void) {//新建单链表,并将建好的单链表首结点地址返回
    struct cell* head, * tmp, * p;
    head = tmp = p = NULL;
    int n;
    scanf("%d", &n);
    if (n == 0)
        return NULL;
    head = (struct cell*)malloc(sizeof(struct cell));
    head->x = n;
    scanf("%d", &n);
    p = head;
    while (n != 0) {
        tmp = (struct cell*)malloc(sizeof(struct cell));
        tmp->x = n;
        p->next = tmp;
        p = tmp;
        p->next = NULL;
        scanf("%d", &n);
    }
    return head;//返回单链表头
}
struct cell* del2one(struct cell* head) {//删除重复结点只保留一个,head是单链表首结点指针
    struct cell* p,*p0,*r;     //r指向p0之前的节点,p0指向待比较的节点
    p = head;
    while (p != NULL) {
        r = p;
        p0 = p->next;
        while (p0 != NULL) {
            if (p0->x == p->x) {  //当有重复元素
                r->next = p0->next;
                p0 = r ->next;
            }
            else {
                r = r->next;
                p0 = r->next;
            }
        }
        p = p->next;
    }
    return head;//返回删除重复结点的单链表头
}
void print(struct cell* head) {//打印整个单链表,head是单链表首结点指针
    struct cell* p;
    printf("%d", head->x);
    p = head->next;
    while (p != NULL) {
        printf(" %d", p->x);
        p = p->next;
    }
}
void release(struct cell* head) {//释放单链表空间,head是单链表首结点指针
    struct cell* p;
    while (head != NULL) {
        p = head;
        head = p->next;
        free(p);
    }
}
int main(void) {
    struct cell* head;
    head = build();
    head = del2one(head);
    if (head != NULL)
        print(head);
    else
        printf("NULL");
    release(head);
}

3. (程序题)

题目编号 :Exp09-Basic03

题目名称:求单链表中间结点

题目描述:请填写缺失代码完成程序,实现如下功能:

首先根据键盘随机输入,以0结束的若干非零整数建立单链表;

然后寻找处于链表中间位置的结点,若中间结点有两个,则设定前一个为中间位置结点;

最后将从中间结点开始到链表尾各结点值输出,相邻数字间以一个西文空格间隔,最后一个数字后无任何字符。

若是空链表,则输出NULL。

例如,

输入:5 4 2 1 3 0 

输出:2 1 3

输入: 4 2 1 3 3 2 0 

输出:1 3 3 2

#include <stdio.h>
#include <malloc.h>
struct cell {//单链表结点结构体定义
    int x;
    struct cell* next;
};
struct cell* build(void) {//新建单链表,并将建好的单链表首结点地址返回
    struct cell* head, * tmp, * p;
    head = tmp = p = NULL;
    int n;
    scanf("%d", &n);
    if (n == 0)
        return NULL;
    head = (struct cell*)malloc(sizeof(struct cell));
    head->x = n;
    p = head;
    p->next = NULL;
    scanf("%d", &n);
    while (n != 0) {
        tmp = (struct cell*)malloc(sizeof(struct cell));
        tmp->x = n;
        p->next = tmp;
        p = tmp;
        p->next = NULL;
        scanf("%d", &n);
    }
    return head;//返回单链表头
}
struct cell* mid(struct cell* head) {//寻找链表中间位置结点地址并返回,head是单链表首结点指针
    int i=0,n;
    struct cell* p;
    p = head;
    while (p != NULL) {
        i++;
        p = p->next;
    }
    if (i % 2 == 0)
        n = i / 2 - 1;
    else
        n = i / 2;
    p = head;
    while (n != 0) {
        p = p->next;
        n--;
    }
    head = p;
    return head;
}
void print(struct cell* head) {//打印整个单链表,head是单链表首结点指针
    struct cell* p;
    printf("%d", head->x);
    p = head->next;
    while (p->x != 0) {
        printf(" %d", p->x);
        p = p->next;
    }
}
void release(struct cell* head) {//释放单链表空间,head是单链表首结点指针
    struct cell* p;
    while (head != NULL) {
        p = head;
        head = p->next;
        free(p);
    }
}
int main(void) {
    struct cell* head, * half;
    head = build();
    half = mid(head);
    if (half != NULL)
        print(half);
    else
        printf("NULL");
    release(head);
}

4. (程序题)

题目编号:Exp09-Basic04

题目名称:单链表交换两结点

题目描述:请填写缺失代码完成程序,实现如下功能:

首先根据键盘随机输入,以0结束的若干非零整数建立单链表;

然后根据输入的两个索引位置交换链表上的两个结点(链表首元素索引为1,且要交换的两个索引位置不相邻);

最后链表各结点值输出,相邻数字间以一个西文空格间隔,最后一个数字后无任何字符。

若是空链表,则输出NULL。

例如,

输入:1 2 3 4 5 6 0 1 5

输出:5 2 3 4 1 6

输入:0 1 2 3 4 5 6 0 1 5

输出:NULL

#include <stdio.h>
#include <malloc.h>
struct cell {//单链表结点结构体定义
    int x;
    struct cell* next;
};
struct cell* build(void) {//新建单链表,并将建好的单链表首结点地址返回
    struct cell* head, * tmp, * p;
    head = tmp = p = NULL;
    int n;
    scanf("%d", &n);
    if (n == 0)
        return NULL;
    head = (struct cell*)malloc(sizeof(struct cell));
    head->x = n;
    p = head;
    p->next = NULL;
    scanf("%d", &n);
    while (n != 0) {
        tmp= (struct cell*)malloc(sizeof(struct cell));
        tmp->x = n;
        p->next = tmp;
        p = tmp;
        p->next = NULL;
        scanf("%d", &n);
    }
    
    return head;//返回单链表头
}
struct cell* swap(struct cell* head, int m, int n) {//交换索引为m和n的两个结点,head是单链表首结点指针
    if (head == NULL) return NULL;
    struct cell* pm = head, * pn = head;
    struct cell* pm0 = NULL, * pn0 = NULL;
    struct cell* tmp;
    int i;
    for (i = 1; i < m && pm != NULL; i++) {
        pm0 = pm;
        pm = pm->next;
    }
    for (i = 1; i < n && pn != NULL; i++) {
        pn0 = pn;
        pn = pn->next;
    }
    if (pm != NULL && pn != NULL && m != n) {//索引为m,n的结点位于链表中间
        if (pm0 != NULL && pn0 != NULL) {
            tmp = pn->next;
            pm0->next = pn;
            pn->next = pm->next;
            pn0->next = pm;
            pm->next = tmp;
        }
        if (pm0 == NULL && pn0 != NULL) {   //即pm为head
            tmp = pm->next;
            pn0->next = pm;
            pm->next = pn->next;
            pn->next = tmp;
            head = pn;
        }
        if (pm0 != NULL && pn0 == NULL) {  //pn为head
            tmp = pn->next;
            pn->next = pm->next;
            pm0->next = pn;
            pm->next = tmp;
            head = pm;
        }
    }
    return head;
}
void print(struct cell* head) {//打印整个单链表,head是单链表首结点指针
    struct cell* p;
    printf("%d", head->x);
    p = head->next;
    while (p->x != 0) {
        printf(" %d", p->x);
        p = p->next;
    }
}
void release(struct cell* head) {//释放单链表空间,head是单链表首结点指针
    struct cell* p;
    while (head != NULL) {
        p = head;
        head = p->next;
        free(p);
    }
}
int main(void) {
    struct cell* head;
    int m, n;
    head = build();
    scanf("%d%d", &m, &n);
    head = swap(head, m, n);
    if (head != NULL)
        print(head);
    else
        printf("NULL");
    release(head);
}

5. (程序题)

题目编号 :Exp09-Basic05,GJBook3例-13-04

题目名称:单链表存储法雷序列

题目描述:请填写缺失代码完成程序,实现如下功能:

给定一个正整数n,用单链表递增存储n阶法雷序列各项值。n阶法雷序列是把所有不可约分的分数j/i(0<i≤n; 0≤j≤i)递增排序的序列。

输入一个正整数n;输出n阶法雷序列各项分数形式,分数的分子和分母间以/连接,各个分数间以一个西文空格间隔,最后一个数字后无任何字符。若是空链表或n不符合要求,则输出NULL。

例如,

输入:3 

输出:0/1 1/3 1/2 2/3 1/1

这个就是教材上面的程序,完全按照上面的思路来的orz

#include <stdio.h>
#include <malloc.h>
struct  farlei_item {
    int   numerator, denominator;   // 分子、分母
    struct  farlei_item* next;   // 连接部分
};
typedef  struct  farlei_item* farleipointer;
int  gcd(int x, int y) {    /*  求最大公约数 */
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
/*构造法雷序列,并返回序列头指针*/
farleipointer farlei(int n) {
    int i, j;
    farleipointer fn, r, r0, p;
    fn = r = r0 = p = NULL;
    if (n < 1)
        return NULL; //如果n<=0,则没有法雷序列
    fn = (farleipointer)malloc(sizeof(struct farlei_item));  //构造0/1
    fn->numerator = 0;
    fn->denominator = 1;

    p = (farleipointer)malloc(sizeof(struct farlei_item));   //构造1/1
    p->numerator = 1;
    p->denominator = 1;

    fn->next = p;
    p->next = NULL;
    for (i = 2; i <= n; i++)
        for (j = 1; j < i; j++)
            if (gcd(i, j) == 1) {
                r = fn;
                while (j * r->denominator > i * r->numerator) {
                    r0 = r; r = r->next;
                }//j/i插入到r0,r之间
                p= (farleipointer)malloc(sizeof(struct farlei_item));
                p->numerator = j;
                p->denominator = i;
                r0->next = p;
                p->next = r;

            }

    return fn;

}

void print(farleipointer fn) {//输出fn引导的法雷序列
    farleipointer p;
    p = fn;
    printf("%d/%d", p->numerator, p->denominator);
    p = p->next;
    while (p != NULL) {
        printf(" %d/%d", p->numerator, p->denominator);
        p = p->next;
    }
}

void release(farleipointer head) {//释放单链表空间,head是单链表首结点指针
    farleipointer p;
    while(head!=NULL){
        p = head;
        head = p->next;
        free(p);
    }
}

int main(void) {
    int n;
    farleipointer fn;
    scanf("%d", &n);
    fn = farlei(n); //生成n级法雷序列
    if (fn != NULL)
        print(fn);
    else
        printf("NULL");
    release(fn);
    return 0;

}

6. (程序题)

题目编号:Exp09-Enhance03

题目名称:合并单链表

题目描述:请填写缺失代码完成程序,实现如下功能:

    首先从键盘输入一行以0结束的若干非零整数,建立一个单链表,输入的整数顺序为数字非递减顺序;

    然后以同样的方式,仍在第一行继续输入并建立第二个单链表;

    之后将两个链表合并形成一个新链表,使得新链表依然保持数字非递减顺序;

    最后验证输出新链表所有值,相邻数字间以一个西文空格间隔,最后一个数字后无任何字符。若是空链表,则输出NULL。

例如,

    输入:2 3 4 4 5 6 0 1 3 4 6 7 0

    输出:1 2 3 3 4 4 4 5 6 6 7

    输入:0 0

    输出:NULL

#include <stdio.h>
#include <malloc.h>
struct cell {//单链表结点结构体定义
    int x;
    struct cell* next;
};
struct cell* build(void) {//新建单链表,并将建好的单链表首结点地址返回
    struct cell* head, * tmp, * tail;
    head = tmp = tail = NULL;
    int n, i;
    scanf("%d", &n);
    if (n == 0)
        return NULL;
    head = (struct cell*)malloc(sizeof(struct cell));
    head->x = n;
    tail = head;
    tail->next = NULL;
    scanf("%d", &n);
    while (n != 0) {
        tmp = (struct cell*)malloc(sizeof(struct cell));
        tmp->x = n;
        tail->next = tmp;
        tail = tmp;
        tail->next = NULL;
        scanf("%d", &n);
    }
    return head;//返回单链表头
}
struct cell* combine(struct cell* p, struct cell* q) {//合并两个链表p和q
    struct cell* head = NULL, * p0 = NULL, * q0 = NULL, * r = NULL;
    if (p == NULL && q != NULL) return q;
    if (p != NULL && q == NULL) return p;
    if (p == NULL && q == NULL) return NULL;
    head = p;//head当头指针
    q0 = q; 
    while (q0 != NULL) {
        p = head;
        r = q0;  //r保存要插入的结点
        q = q->next;   //q的头指针指向下一个
        if (p->x < r->x) {
            p0 = p;
            p = p->next;
            while (p->x < r->x && p->next != NULL) {
                p0 = p;
                p = p->next;
            }
            if (p->next == NULL) {
                p->next = r;
                r->next = NULL;
            }
            else {
                r->next = p;
                p0->next = r;
            }
        }
        else {
            r->next = p;
            head = r;
        }
        q0 = q;
    }
    return head;
}
void print(struct cell* head) {//打印整个单链表,head是单链表首结点指针
    struct cell* p;
    printf("%d", head->x);
    p = head->next;
    while (p != NULL) {
        printf(" %d", p->x);
        p = p->next;
    }
}
void release(struct cell* head) {//释放单链表空间,head是单链表首结点指针
    struct cell* p;
    while (head != NULL) {
        p = head;
        head = p->next;
        free(p);
    }
}
int main(void) {
    struct cell* head1, * head2, * result;
    head1 = build();
    head2 = build();
    result = combine(head1, head2);
    if (result != NULL)
        print(result);
    else
        printf("NULL");
    release(result);
    return 0;
}

7. (程序题)

题目编号:Exp09-Enhance04,GJBook3例-13-02

题目名称:排序单链表

题目描述:请填写缺失代码完成程序,实现如下功能:

    首先根据键盘随机输入一行以0结束的若干非零整数建立单链表;

    然后递增排序链表;

    最后验证输出排序后链表中所有值,相邻数字间以一个西文空格间隔,最后一个数字后无任何字符。

    若是空链表,则输出NULL。

例如,

    输入:2 3 6 4 5 0 

    输出:2 3 4 5 6

    输入:0 2 3 4 

    输出:NULL

(排序第一次自己写的太复杂了,借鉴了一下别人的思路orz)

#include <stdio.h>
#include <malloc.h>
struct cell {//单链表结点结构体定义
    int x;
    struct cell* next;
};
struct cell* build(void) {//新建单链表,并将建好的单链表首结点地址返回
    struct cell* head, * tmp, * tail;
    head = tmp = tail = NULL;
    int n;
    scanf("%d", &n);
    if (n == 0)
        return NULL;
    head = (struct cell*)malloc(sizeof(struct cell));
    head->x = n;
    tail= head;
    tail->next = NULL;
    scanf("%d", &n);
    while (n != 0) {
        tmp = (struct cell*)malloc(sizeof(struct cell));
        tmp->x = n;
        tail->next = tmp;
        tail = tmp;
        tail->next = NULL;
        scanf("%d", &n);
    }
    return head;//返回单链表头
}
struct cell* sort(struct cell* head) {//递增排序链表,head是单链表首结点指针
    struct cell* p, * p0, * r, * r0, * q;
    p = p0 = r = r0 = q = NULL;
    p = head;
    p = p->next;
    p0 = head;
    while(p!=NULL){
        r = head;
        while (r->x < p->x && r != p) {
            r0 = r;
            r = r->next;
        }
        if (r != p) {     //r0比p小,r比p大
            q = p;       //此处把p所指的结点保存,根据r的位置分情况
            p0->next = p->next;
            p = p0;
            if (r == head) {
                q->next = r;
                head = q;
            }
            else {            //将q插入r0与r之间
                q->next = r;
                r0->next = q;
            }
        }
        p0 = p;
        p = p->next;
    }
    return head;
}   /*  sort */


void print(struct cell* head) {//打印整个单链表,head是单链表首结点指针
    struct cell* p;
    printf("%d", head->x);
    p = head->next;
    while (p->x != 0) {
        printf(" %d", p->x);
        p = p->next;
    }
}
void release(struct cell* head) {//释放单链表空间,head是单链表首结点指针
    struct cell* p;
    while (head != NULL) {
        p = head;
        head = p->next;
        free(p);
    }
}
int main(void) {
    struct cell* head;
    head = build();
    if (head != NULL) {
        head = sort(head);
        print(head);
    }
    else
        printf("NULL");
    release(head);
    return 0;
}

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Scarlett_19

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值