C数据结构与算法——单链表 应用

实验任务

(1) 掌握单链表结构及其 C 语言实现;
(2) 掌握插入、删除等基本算法;
(3) 掌握单链表的基本应用(将两个有序线性表合并为一个有序表)。

实验内容

  • 使用 C 语言实现单链表的类型定义与算法函数;
  • 编写 main()函数,合理调用函数实现以下功能:
    • 创建 2 个单链表 L1、L2(带头结点,用于存储表长);
    • 初始化 L1 数据并显示(斐波拉契序列前 2-11 项):1、2、、…、89;
    • 随机产生 L2 数据 10 个:
      • 第 1 个数为 4,其后每个数字比其前趋随机增加1~9,显示L2 内容
      • 附加分 20:再用洗牌算法随机打乱(10 次)L2 中的数据,显示L2的内容
    • 将 L2 中的结点按从前往后的顺序一个一个有序合并到L1 中(即每次都将L2中的首元结点摘下链入 L1 中正确位置,完成后 L2 成为空表),显示L1的内容;
    • 随机删除 L1 中第 1~20 个元素,显示 L1 的内容;
    • 随机产生 1 个[1, 100]之间的数字插入到 L1 中并保持有序,显示L1的内容;
    • 销毁 L1 和 L2,即将所有结点空间归还系统。

实验源码

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

#define NUM_L1 10
#define NUM_L2 10

typedef enum {
    ERROR,
    OK
} status;

typedef enum {
    FALSE,
    TRUE
} boolean;

typedef int ElemType;

typedef struct LNode { // 链表的定义
    ElemType data;
    struct LNode *next;
} LNode, *LinkList;

status InitList(LinkList list); // 链表的初始化

void PrintList(LinkList list); // 打印链表

void Fibonacci(LinkList list, int length); // 创建 L1

void RandomNumber(LinkList list, int num); // 创建 L2

void knuthShuffle(LinkList list, int num); // 洗牌算法(交换值的方式)

void swapInt(ElemType *elem1, ElemType *elem2); // 辅助洗牌算法 交换元素

ElemType *GetElem(LinkList list, int num); // 辅助洗牌算法 取值

void BubbleSort(LinkList list); // 冒泡排序(值交换)

void MergeList_L(LinkList list1, LinkList list2); // L2 合并到 L1 并保持有序

status DeleteElem(LinkList list, int i); // 随机删除 L1 中的第i个元素

status InsertElem(LinkList list, ElemType randElem); // 随机插入一个元素到 L1中 并保持有序

boolean IsEmpty(LinkList list); // 判断链表是否为空 [辅助插入]

status InitList(LinkList list) {
    list = (LinkList) malloc(sizeof(LNode));
    if (list == NULL) {
        return ERROR;
    }
    list->next = NULL;
    list->data = 0;
    return OK;
}

void PrintList(LinkList list) {
    LNode *temp;
    int count = 0;
    printf("->{%2d}", list->data);
    for (temp = list->next; temp != NULL; temp = temp->next) {
        printf("->(%2d)", temp->data);
        if (++count % 10 == 0 && count != list->data) {
            printf("\n        ");
        }
    }
    printf("\n");
}

void Fibonacci(LinkList list, int length) {
    int num1 = 0;
    int num2 = 1;
    LNode *temp, *tail;
    tail = list;
    for (int i = 1; i <= length; i++) {
        temp = (LinkList) malloc(sizeof(LNode));
        if (i % 2 != 0) {
            num1 += num2;
            temp->data = num1;
        } else {
            num2 += num1;
            temp->data = num2;
        }
        tail->next = temp;
        tail = temp;
    }
    tail->next = NULL;
    list->data = length;
}

void RandomNumber(LinkList list, int num) {
    LNode *temp, *tail;
    ElemType tElem; // 临时存储数据 tempElem
    tail = list;
    for (int i = 0; i < num; i++) {
        temp = (LinkList) malloc(sizeof(LNode));
        if (i != 0) {
            temp->data = tElem + rand() % 9 + 1;
        } else {
            temp->data = 4;
        }
        tElem = temp->data;
        tail->next = temp;
        tail = temp;
    }
    tail->next = NULL;
    list->data = num;
}

void knuthShuffle(LinkList list, int num) {
    for (int i = num - 1; i >= 1; i--) {
        swapInt(GetElem(list, i), GetElem(list, (rand() % (i + 1))));
    }
}

void swapInt(ElemType *elem1, ElemType *elem2) {
    ElemType temp;
    temp = *elem1;
    *elem1 = *elem2;
    *elem2 = temp;
}

ElemType *GetElem(LinkList list, int num) {
    LNode *temp = list->next;
    int j = 1;
    while (temp && j < num) {
        temp = temp->next;
        ++j;
    }
    return &(temp->data);
}

void BubbleSort(LinkList list) {
    LNode *pA, *pB, *pTail = NULL;
    LNode *pHead = list->next;
    while (pTail != pHead) {
        pB = pHead;
        int count = -1;
        while (pB->next != pTail) {
            pA = pB->next;
            if (pA->data < pB->data) {
                ElemType temp = pA->data;
                pA->data = pB->data;
                pB->data = temp;
                count++;
            }
            pB = pB->next;
        }
        if (count == -1) {
            return;
        }
        pTail = pB;
    }
}

void MergeList_L(LinkList list1, LinkList list2) {
    BubbleSort(list2);
    LNode *pL1, *pL2, *pL3;
    pL1 = list1->next;
    pL2 = list2->next;
    pL3 = list1;
    while (pL1 && pL2) {
        if (pL1->data <= pL2->data) {
            pL3->next = pL1;
            pL3 = pL1;
            pL1 = pL1->next;
        } else {
            pL3->next = pL2;
            pL3 = pL2;
            pL2 = pL2->next;
        }
    }
    pL3->next = pL1 ? pL1 : pL2;
    list1->data = list1->data + list2->data;
}

status DeleteElem(LinkList list, int i) {
    LNode *pL = list, *temp;
    int j = 1;
    while (pL->next && j < i) {
        pL = pL->next;
        ++j;
    }
    while (!(pL->next) || j > i) {
        return ERROR;
    }
    temp = pL->next;
    pL->next = temp->next;
    free(temp);
    list->data--;
    return OK;
}

status InsertElem(LinkList list, ElemType randElem) {
    if (IsEmpty(list) || randElem < 1 || randElem > 100) {
        return ERROR;
    }
    LNode *temp;
    temp = (LinkList) malloc(sizeof(LNode));
    temp->next = NULL;
    temp->data = randElem;
    LNode *pL = list->next;
    while (pL->next != NULL) {
        pL = pL->next;
    }
    pL->next = temp;
    list->data++;
    BubbleSort(list);
    return OK;
}

boolean IsEmpty(LinkList list) {
    if (list->next == NULL) {
        return TRUE;
    } else {
        return FALSE;
    }
}

/**
 * <h2>单链表实验</h2>
 * return 0
 */
int main() {

    LNode L1, L2;
    srand(time(NULL));

    printf("=========================== 单链表编程实践 ===========================\n");

    if (InitList(&L1) == OK) {
        printf("【单链表L1已生成】\n");
        Fibonacci(&L1, NUM_L1);
        printf("L1");
        PrintList(&L1);
    }

    if (InitList(&L2) == OK) {
        printf("【单链表L2已生成】\n");
        RandomNumber(&L2, NUM_L2);
        printf("L2");
        PrintList(&L2);
    }

    printf("【Knuth洗牌算法随机打乱L2】\n");
    knuthShuffle(&L2, NUM_L2);
    printf("L2");
    PrintList(&L2);

    printf("【单链表L2有序合并到L1】\n");
    MergeList_L(&L1, &L2);
    printf("L1");
    PrintList(&L1);

    int randNum_10 = rand() % 10 + 1;
    printf("【随机删除L1中第%d个元素】\n", randNum_10);
    DeleteElem(&L1, randNum_10);
    printf("L1");
    PrintList(&L1);

    ElemType randNum_100 = rand() % 100 + 1;
    printf("【随机产生%d插入到L1中】\n", randNum_100);
    InsertElem(&L1, randNum_100);
    printf("L1");
    PrintList(&L1);

    return 0;
}

实验结果

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小丶象

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

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

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

打赏作者

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

抵扣说明:

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

余额充值