数据结构实验---顺序表的合并---链表的基本操作

简介: 数据结构实验---顺序表的合并---链表的基本操作

本篇展示数据结构的两个实验

对顺序表和链表不清楚有以下文章介绍

掌握顺序表和单链表后 实验均为上述的简单应用

顺序表的合并

定义线性表的顺序存储结构,并使用定义的结构实现两个线性表的合并。(建立两个有序顺序表,将两个有序顺序表合并为一个有序顺序表)。
内容要求:
建立有序表:12,23,46,67,85
建立有序表:5,59,94
两个有序顺序表合并为一个有序顺序表,验证代码的正确性。

代码实现

//建立有序表:12,23,46,67,85
//建立有序表:5,59,94
//两个有序顺序表合并为一个有序顺序表,验证代码的正确性。

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

typedef int SLDataType;
typedef struct SeqList
{
   
    SLDataType* a;
    int size;
    int capacity;
}SeqList;

void SListInit(SeqList* ps)
{
   
    //assert(ps);
    ps->size = 0;
    ps->capacity = 4;
    ps->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);
    if (ps->a == NULL)
    {
   
        perror("malloc fail");
        return;
    }
}

void SListDestroy(SeqList* ps)
{
   
    assert(ps);
    ps->a = NULL;
    ps->capacity = 0;
    ps->size = 0;
}

void SListCheckCapacity(SeqList* ps)
{
   
    assert(ps);
    if (ps->size == ps->capacity)
    {
   
        SLDataType* tmp = NULL;
        tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType)*(ps->capacity) * 2);
        if (tmp == NULL)
        {
   
            perror("realloc fail");
            return;
        }
        ps->a = tmp;
        ps->capacity *= 2;
        //printf("The capacity now:%d\n", ps->capacity);
    }
    else
    {
   
        return;
    }
}

void SListPushBack(SeqList* ps, SLDataType x)
{
   
    assert(ps);
    SListCheckCapacity(ps);
    ps->a[ps->size] = x;
    ps->size++;
}

void SListPrint(SeqList* ps)
{
   
    assert(ps);
    for (int i = 0; i < ps->size; i++)
    {
   
        printf("%d ", ps->a[i]);
    }
    printf("\n");
}

void SListMerge(SeqList* ps1, SeqList* ps2)
{
   
    assert(ps1);
    assert(ps2);
    SeqList ps;
    SListInit(&ps);
    for (int i = 0; i < ps1->size; i++)
    {
   
        SListPushBack(&ps, ps1->a[i]);
    }
    for (int i = 0; i < ps2->size; i++)
    {
   
        SListPushBack(&ps, ps2->a[i]);
    }
    printf("The result of merging two seqlists is:\n");
    SListPrint(&ps);
}

int main()
{
   
    SeqList ps1;
    SeqList ps2;
    SListInit(&ps1);
    SListInit(&ps2);
    int quantity1 = 0, quantity2 = 0, input = 0;

    printf("Input quantity of seqlist1-> ");
    scanf("%d", &quantity1);
    for (int i = 0; i < quantity1; i++)
    {
   
        scanf("%d", &input);
        SListPushBack(&ps1, input);
    }

    printf("Input quantity of seqlist2-> ");
    scanf("%d", &quantity2);
    for (int i = 0; i < quantity2; i++)
    {
   
        scanf("%d", &input);
        SListPushBack(&ps2, input);
    }

    SListMerge(&ps1, &ps2);
    return 0;
}

代码下载

Gitee下载链接

链表的基本操作

定义线性表的链式存储结构,定义结点类型,并使用定义的结构实现链表的创建,插入,删除、查询、输出等基本操作。
通讯录管理(必做内容) ; 约瑟夫环(选做内容)
必做内容要求:
1.通讯者的结点类型定义如下:
typedef struct {
char num[5] ; //编号
char name[9] ; //姓名
char sex[3] ; //性别
char phone[13]; //电话
char addr[31] ; //地址
]DataType ;
2.线性表的链式存储结构定义如下:
typedef struct node { //结点类型定义
DataType data ; //结点数据域
struct node next ; //结点指针域
} ListNode ;
typedef ListNode
LinkList ;
ListNode * p ; //定义一个指向结点的指针变量
LinkList head ; //定义指向单链表的头指针
3.主控菜单设计要求
程序运行后,给出6个菜单项的内容和输入提示:

  1. 通讯录链表的建立
  2. 通讯者结点的插入
  3. 通讯者结点的查询
  4. 通讯者结点的删除
  5. 通讯录链表的输出
  6. 退出管理系统
        请选择   0——5
    
    使用数字0——5来选择菜单项,其他输入则不起作用。

选做内容要求:
约瑟夫(Joseph)问题的一种描述是:30个旅客同乘一条船,因为严重超载,加上风高浪大,危险万分。因此船长告诉乘客,只有将全船一半的旅客投入海中,其余人才能幸免于难。无奈,大家只好同意这种办法,并议定30个人围成一圈,由第一个人数起,依次报数,数到第9人,便把他投入大海,然后再从他的下一个人数起,数到第9人,再将他扔进大海中,如此循环地进行,直到剩下15个乘客为止。问哪些位置是将被扔下大海的位置?

1.利用单向循环链表存储结构模拟此过程,按照出列的顺序输出各人的编号。
2.为了不失一般性,将30改为一个任意输入的正整数n,而报数上限(原为9)也为一个任选的正整数k。这样该算法描述如下:
(1)创建含有n个结点的单循环链表;
(2)生者与死者的选择:
p指向链表第一个结点,初始i 置为1;
while (i<=n/2) //删除一半的结点
{ 从p指向的结点沿链前进k-1步;
删除第k个结点(q所指向的结点);p指向q的下一个结点;
输出其位置q->data;
i自增1;
}
(3)输出所有生者的位置。

3.测试结果
对于总人数30,报数上限为9,则
死者编号为:9,18,27,6,16,26,7,19,30,12,24,8,22,5,23
生者编号为:1,2,3,4,10,11,13,14,15,17,20,21,25,28,29

代码实现

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdbool.h>

typedef  struct
{
   
    char  num[5];    //编号
    char  name[9];   //姓名
    char  sex[3];     //性别
    char  phone[13];  //电话
    char  addr[31];   //地址
}DataType;

typedef struct node
{
   
    DataType data;
    struct node* next;
}ListNode;

//头节点用head
//定义一个指向结点的指针变量 ListNode* p;

ListNode* BuyListNode(DataType x);

void ListNodePush(ListNode** phead);

DataType Buynewdata();

void ListNodePrint(ListNode** phead);

int ListNodeFind(ListNode* head, const char* Findname);

void ListNodePop(ListNode** phead, const char* Popname);

ListNode* BuyListNode(DataType x)
{
   
    ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
    if (newnode == NULL)
    {
   
        perror("malloc fail");
        return NULL;
    }
    newnode->next = NULL;
    newnode->data = x;
    return newnode;
}

DataType Buynewdata()
{
   
    DataType newdata;
    printf("请依次输入编号 姓名 性别 电话 地址\n");
    scanf("%s %s %s %s %s",
        newdata.num, newdata.name, newdata.sex, newdata.phone, newdata.addr);
    return  newdata;
}

void ListNodePush(ListNode** phead)
{
   
    assert(phead);
    ListNode* newnode = BuyListNode(Buynewdata());
    if (*phead == NULL)
    {
   
        *phead = newnode;
    }
    else
    {
   
        newnode->next = *phead;
        *phead = newnode;
    }
}

void ListNodePrint(ListNode** phead)
{
   
    ListNode* cur = *phead;
    printf("%-5s%-10s%-8s%-13s%-31s\n",
        "编号", "姓名", "性别", "电话", "地址");
    while (cur)
    {
   
        printf("%-5s%-10s%-8s%-13s%-31s\n",
            cur->data.num, cur->data.name, cur->data.sex,
            cur->data.phone, cur->data.addr);
        cur = cur->next;
    }
}

int ListNodeFind(ListNode* head, const char* Findname)
{
   
    ListNode* cur = head;
    while (cur)
    {
   
        if (strcmp(Findname, cur->data.name) == 0)
        {
   
            printf("找到了,该人的信息如下\n");
            printf("%-5s%-10s%-8s%-13s%-31s\n",
                "编号", "姓名", "性别", "电话", "地址");
            printf("%-5s%-10s%-8s%-13s%-31s\n",
                cur->data.num, cur->data.name, cur->data.sex,
                cur->data.phone, cur->data.addr);
            return 1;
        }
        else
        {
   
            cur = cur->next;
        }
    }
    printf("找不到信息\n");
    return 0;
}

void ListNodePop(ListNode** phead, const char* Popname)
{
   
    assert(*phead);
    assert(phead);
    if (ListNodeFind(*phead, Popname))
    {
   
        ListNode* Findnode = *phead;
        ListNode* prev = *phead;
        while (strcmp(Findnode->data.name, Popname) != 0)
        {
   
            prev = Findnode;
            Findnode = Findnode->next;
        }
        prev->next = Findnode->next;
        free(Findnode);
        Findnode = NULL;
        printf("删除该人信息成功\n");
        return;
    }
    else
    {
   
        printf("找不到该人信息\n");
        return;
    }
}

void menu()
{
   
    printf("*********************************************\n");
    printf("****1.建立信息表************** 2.插入信息 ****\n");
    printf("****3.查询信息  ************** 4.删除信息 ****\n");
    printf("****5.打印信息  ************** 0.退出     ****\n");
    printf("*********************************************\n");
}

void SetupListNode(ListNode** phead)
{
   
    int num = 0;
    printf("建立链表成功,开始录入信息\n");
    printf("输入要录取信息的个数->");
    scanf("%d", &num);
    while (num--)
    {
   
        ListNodePush(phead);
    }
}

void FindFunction(ListNode* head)
{
   
    char Findname[20] = {
    0 };
    printf("输入要查找的人名");
    scanf("%s", Findname);
    ListNodeFind(head, Findname);
}

void PopFunction(ListNode** phead)
{
   
    char Popname[20] = {
    0 };
    printf("输入要查找的人名");
    scanf("%s", Popname);
    ListNodePop(phead, Popname);
}

int main()
{
   
    menu();
    int input = 0;
    ListNode* head = NULL;
    do
    {
   
        printf("请选择->");
        scanf("%d", &input);
        switch (input)
        {
   
        case 1:
            SetupListNode(&head);
            break;
        case 2:
            if (head == NULL)
            {
   
                printf("通讯录还未建立,请先建立\n");
                break;
            }
            else
            {
   
                ListNodePush(&head);
                break;
            }
        case 3:
            if (head == NULL)
            {
   
                printf("通讯录还未建立,请先建立\n");
                break;
            }
            else
            {
   
                FindFunction(head);
                break;
            }
        case 4:
            if (head == NULL)
            {
   
                printf("通讯录还未建立,请先建立\n");
                break;
            }
            else
            {
   
                PopFunction(&head);
                break;
            }
        case 5:
            if (head == NULL)
            {
   
                printf("通讯录还未建立,请先建立\n");
                break;
            }
            else
            {
   
                ListNodePrint(&head);
                break;
            }
        case 0:
            break;
        default:
            printf("请重新选择\n");
            break;
        }
        menu();
    } while (input);
    return 0;
}
相关文章
|
1月前
|
存储 算法 编译器
数据结构实验之矩阵的运算器(二维数组)
本实验旨在通过团队合作,掌握数组和矩阵相关运算的代码实现,包括矩阵的加减、数乘、转置、乘法、n次方及行列式的计算。实验过程中,成员们需分工协作,解决编程难题,最终实现一个功能完备的矩阵计算器。通过本实验,不仅锻炼了编程能力,还加深了对数学概念的理解,同时培养了团队合作精神。
59 4
|
1月前
数据结构实验之串模式匹配问题
本实验旨在掌握串模式匹配技术,通过创建文本文件、实现单词计数与定位功能,最终构建一个包含文件建立、单词统计与定位、程序退出等选项的主菜单,以增强对字符串处理的理解与应用能力。
53 4
|
1月前
|
算法
数据结构实验之最长公共子序列
本实验旨在通过编程实践帮助学生理解串的基本概念及求解最长公共子序列的算法。实验内容包括使用动态规划方法设计并实现算法,以找出给定两序列的最大公共子序列。示例代码展示了如何通过构建状态矩阵和回溯路径来找到解决方案。实验总结指出,`memset()`函数用于内存初始化,且对于特定输入,程序能正确输出最长公共子序列之一。
56 4
|
1月前
|
算法
数据结构实验之操作系统打印机管理器问题
本实验旨在通过实现操作系统中的打印机管理器问题,掌握队列的基本操作如入队、出队等,利用队列的先进先出特性解决先申请先打印的问题。实验包括队列的初始化、入队、出队、打印队列内容等功能,并通过菜单式界面进行交互。实验结果显示基本功能可正常执行,但在连续操作时存在执行失败的情况,需进一步优化。
43 4
|
1月前
|
存储 算法 Perl
数据结构实验之链表
本实验旨在掌握线性表中元素的前驱、后续概念及链表的建立、插入、删除等算法,并分析时间复杂度,理解链表特点。实验内容包括循环链表应用(约瑟夫回环问题)、删除单链表中重复节点及双向循环链表的设计与实现。通过编程实践,加深对链表数据结构的理解和应用能力。
57 4
|
27天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
53 5
|
1月前
|
存储
顺序表和链表(2)
【10月更文挑战第23天】
顺序表和链表(2)
|
1月前
|
机器学习/深度学习 存储 算法
数据结构实验之二叉树实验基础
本实验旨在掌握二叉树的基本特性和遍历算法,包括先序、中序、后序的递归与非递归遍历方法。通过编程实践,加深对二叉树结构的理解,学习如何计算二叉树的深度、叶子节点数等属性。实验内容涉及创建二叉树、实现各种遍历算法及求解特定节点数量。
85 4
|
1月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
56 4
|
1月前
|
算法
数据结构之购物车系统(链表和栈)
本文介绍了基于链表和栈的购物车系统的设计与实现。该系统通过命令行界面提供商品管理、购物车查看、结算等功能,支持用户便捷地管理购物清单。核心代码定义了商品、购物车商品节点和购物车的数据结构,并实现了添加、删除商品、查看购物车内容及结算等操作。算法分析显示,系统在处理小规模购物车时表现良好,但在大规模购物车操作下可能存在性能瓶颈。
49 0