C语言动态顺序表实例代码

接下来我将详细讲解 C 语言动态顺序表的实现过程。首先我们需要先了解顺序表的概念,顺序表是一种线性表的存储结构,它在物理上采用一组连续的内存空间来存储线性表的数据元素,并且对于顺序表的元素,我们可以按照元素下标进行随机存取。接下来我们就可以开始进行动态顺序表的实现了。

动态顺序表的实现

初步设计

首先我们需要先建立一个动态顺序表结构体,它包含了以下几个基本成员变量:

typedef struct {
    int *elem;      // 存储空间的基地址
    int length;     // 当前顺序表的长度
    int capacity;   // 顺序表的初始容量
} SeqList;

我们可以使用 malloc() 函数在内存中申请空间,对应到模拟该数据结构中,初始化时需分配初始空间。在动态顺序表中,我们需要提供插入、删除、查找等操作,下面是对应的函数实现:

插入元素

bool insert(SeqList *L, int index, int value) {
    // 首先需要判断插入位置的合法性
    if (index < 1 || index > L->length + 1) {
        return false;
    }

    // 需要判断顺序表是否已满
    if (L->length >= L->capacity) {
        // 如果已满,需要进行扩容
        int *new_base = (int *)realloc(L->elem, 
            (L->capacity + LIST_INCREMENT) * sizeof(int));

        // 判断是否分配成功
        if (!new_base) {
            return false;
        }

        // 修改当前顺序表的存储基址和容量
        L->elem = new_base;
        L->capacity += LIST_INCREMENT;
    }

    // 进行元素插入,需要从后往前依次将元素后移
    for (int i = L->length; i >= index; i--) {
        L->elem[i] = L->elem[i - 1];
    }
    L->elem[index - 1] = value;
    // 插入成功后需要将顺序表长度加一
    L->length++;
    return true;
}

删除元素

bool delete(SeqList *L, int index) {
    // 首先需要判断删除位置的合法性
    if (index < 1 || index > L->length) {
        return false;
    }

    // 进行元素删除,需要从该位置开始将元素依次向前移动
    for (int i = index; i < L->length; i++) {
        L->elem[i - 1] = L->elem[i];
    }
    // 删除后需要将顺序表长度减一
    L->length--;
    return true;
}

查找元素

int search(SeqList *L, int value) {
    for (int i = 0; i < L->length; i++) {
        if (L->elem[i] == value) {
            // 找到后返回该元素在顺序表中的位置
            return i + 1;
        }
    }
    // 找不到返回 -1
    return -1;
}

示例说明

下面提供两个示例来说明动态顺序表的使用。

示例一:对一个用户输入的数组建立一个动态顺序表

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

#define LIST_INIT_SIZE 100
#define LIST_INCREMENT 10

typedef struct {
    int *elem;
    int length;
    int capacity;
} SeqList;

bool insert(SeqList *L, int index, int value) {
    // 首先需要判断插入位置的合法性
    if (index < 1 || index > L->length + 1) {
        return false;
    }

    // 需要判断顺序表是否已满
    if (L->length >= L->capacity) {
        // 如果已满,需要进行扩容
        int *new_base = (int *)realloc(L->elem, 
            (L->capacity + LIST_INCREMENT) * sizeof(int));

        // 判断是否分配成功
        if (!new_base) {
            return false;
        }

        // 修改当前顺序表的存储基址和容量
        L->elem = new_base;
        L->capacity += LIST_INCREMENT;
    }

    // 进行元素插入,需要从后往前依次将元素后移
    for (int i = L->length; i >= index; i--) {
        L->elem[i] = L->elem[i - 1];
    }
    L->elem[index - 1] = value;
    // 插入成功后需要将顺序表长度加一
    L->length++;
    return true;
}

bool delete(SeqList *L, int index) {
    // 首先需要判断删除位置的合法性
    if (index < 1 || index > L->length) {
        return false;
    }

    // 进行元素删除,需要从该位置开始将元素依次向前移动
    for (int i = index; i < L->length; i++) {
        L->elem[i - 1] = L->elem[i];
    }
    // 删除后需要将顺序表长度减一
    L->length--;
    return true;
}

int search(SeqList *L, int value) {
    for (int i = 0; i < L->length; i++) {
        if (L->elem[i] == value) {
            // 找到后返回该元素在顺序表中的位置
            return i + 1;
        }
    }
    // 找不到返回 -1
    return -1;
}

int main() {
    int n, temp;
    SeqList list;
    list.elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));
    list.capacity = LIST_INIT_SIZE;
    list.length = 0;

    printf("请输入数组长度n:");
    scanf("%d", &n);

    for (int i = 1; i <= n; i++) {
        printf("请输入第%d个元素:", i);
        scanf("%d", &temp);
        insert(&list, i, temp);
    }

    printf("当前顺序表中的元素为:");
    for (int i = 0; i < list.length; i++) {
        printf("%d ", list.elem[i]);
    }
    printf("\n");

    return 0;
}

运行效果如下:

请输入数组长度n:5
请输入第1个元素:1
请输入第2个元素:3
请输入第3个元素:5
请输入第4个元素:7
请输入第5个元素:9
当前顺序表中的元素为:1 3 5 7 9 

示例二:使用动态顺序表实现一个小游戏

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

#define LIST_INIT_SIZE 100
#define LIST_INCREMENT 10

typedef struct {
    int *elem;
    int length;
    int capacity;
} SeqList;

bool insert(SeqList *L, int index, int value) {
    // 首先需要判断插入位置的合法性
    if (index < 1 || index > L->length + 1) {
        return false;
    }

    // 需要判断顺序表是否已满
    if (L->length >= L->capacity) {
        // 如果已满,需要进行扩容
        int *new_base = (int *)realloc(L->elem, 
            (L->capacity + LIST_INCREMENT) * sizeof(int));

        // 判断是否分配成功
        if (!new_base) {
            return false;
        }

        // 修改当前顺序表的存储基址和容量
        L->elem = new_base;
        L->capacity += LIST_INCREMENT;
    }

    // 进行元素插入,需要从后往前依次将元素后移
    for (int i = L->length; i >= index; i--) {
        L->elem[i] = L->elem[i - 1];
    }
    L->elem[index - 1] = value;
    // 插入成功后需要将顺序表长度加一
    L->length++;
    return true;
}

bool delete(SeqList *L, int index) {
    // 首先需要判断删除位置的合法性
    if (index < 1 || index > L->length) {
        return false;
    }

    // 进行元素删除,需要从该位置开始将元素依次向前移动
    for (int i = index; i < L->length; i++) {
        L->elem[i - 1] = L->elem[i];
    }
    // 删除后需要将顺序表长度减一
    L->length--;
    return true;
}

int search(SeqList *L, int value) {
    for (int i = 0; i < L->length; i++) {
        if (L->elem[i] == value) {
            // 找到后返回该元素在顺序表中的位置
            return i + 1;
        }
    }
    // 找不到返回 -1
    return -1;
}

bool playGame(SeqList *L) {
    printf("游戏开始!\n");
    int count = 0;

    // 随机选择一个数
    srand((unsigned)time(NULL));
    int target = rand() % 1000 + 1;

    while (1) {
        int guess;
        printf("请输入您猜测的数字:");
        scanf("%d", &guess);
        count++;

        if (search(L, guess) != -1) {
            printf("您已经猜测过这个数字,请重新输入。\n");
        } else {
            if (guess < target) {
                printf("您输入的数字小了,请再次猜测!\n");
                insert(L, L->length + 1, guess);
            } else if (guess > target) {
                printf("您输入的数字大了,请再次猜测!\n");
                insert(L, L->length + 1, guess);
            } else {
                printf("恭喜您猜对了!您一共猜了%d次。\n", count);
                return true;
            }
        }
    }
}

int main() {
    SeqList list;
    list.elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));
    list.capacity = LIST_INIT_SIZE;
    list.length = 0;

    playGame(&list);

    free(list.elem);
    return 0;
}

运行效果如下:

游戏开始!
请输入您猜测的数字:500
您输入的数字小了,请再次猜测!
请输入您猜测的数字:750
您输入的数字小了,请再次猜测!
请输入您猜测的数字:875
您输入的数字小了,请再次猜测!
请输入您猜测的数字:937
您输入的数字大了,请再次猜测!
请输入您猜测的数字:906
恭喜您猜对了!您一共猜了5次。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言动态顺序表实例代码 - Python技术站

(0)
上一篇 2023年5月30日
下一篇 2023年5月30日

相关文章

  • 基于Matlab实现离散系统分岔图的绘制

    下面我将详细讲解如何基于Matlab实现离散系统分岔图的绘制: 1. 离散系统分岔图绘制原理 在计算非线性动力学系统时,通过方程的参数调整来观察系统的不稳定性、稳定性和边界行为点所形成的“分岔图”。分岔图包含的信息可以告诉我们关于系统的重要性质,如系统的稳定性、周期性和混沌性等。 离散系统分岔图绘制的原理是,利用计算机运行数值模拟算法对离散系统进行仿真模拟,…

    C 2023年5月24日
    00
  • Swift与Objective C的简单对比

    下面是“Swift与Objective C的简单对比”的完整攻略: 简介 Swift是一种由苹果公司发布的新型编程语言,于2014年推出,是一种功能强大和易于使用的编程语言,主要用于iOS、macOS、watchOS和tvOS操作系统的应用开发。Objective-C是苹果公司用来开发iOS和macOS应用程序的主要编程语言,虽然现在Swift已经成为苹果主…

    C 2023年5月22日
    00
  • C++中四种对象生存期和作用域以及static的用法总结分析

    C++中四种对象生存期和作用域以及static的用法总结分析 在C++中,对象是程序中的基本组成单位之一。对象有不同的生存期和作用域,对于理解C++程序的运行过程至关重要。static是一个关键字,它有多种用途。本文将详细介绍C++中四种对象生存期和作用域以及static的用法。 对象的生存期和作用域 C++中的对象根据生存期和作用域的不同可以分为以下四类:…

    C 2023年5月22日
    00
  • c++ #include是怎么样工作的?

    当我们在编写 C++ 程序时, 有时需要使用其它文件中定义的函数或变量,那么我们就需要使用 #include 语句把这个文件包含进来。在 C++ 中,#include 是一个预处理命令。 下面来详细讲解“C++ #include 是怎么样工作的?”的完整攻略: 1. #include 的作用 include 是 C++ 中的一个预处理命令,用于包含一个文件到…

    C 2023年5月23日
    00
  • python爬取之json、pickle与shelve库的深入讲解

    Python爬取之Json、Pickle与Shelve库的深入讲解 在Python爬虫中,经常需要将数据结构序列化以便于存储或传输。Python提供了几种序列化方法,包括Json、Pickle和Shelve。 Json Json是一个轻量级的数据交换格式,可以方便地在不同的编程语言之间进行数据交换。Python提供了Json模块,可以将Python对象序列化…

    C 2023年5月23日
    00
  • C语言围圈报数题目代码实现

    我先来介绍一下 “C语言围圈报数题目代码实现” 是什么: 这是一道经典的数学题目,题目有三个人围成一圈,他们报数,规定报到第三个人的时候要翻过去,也就是从头开始,如此循环,直到只剩下最后一个人。现在我们需要用C语言实现这个过程。 下面是该算法的完整实现,以及代码解析: 思路分析 1.将所有人简化为一个数组,数组的下标表示的是人的编号。2.从第k个人开始循环报…

    C 2023年5月24日
    00
  • C语言实现简单五子棋小游戏

    C语言实现简单五子棋小游戏 本文将详细讲解如何使用C语言实现简单的五子棋小游戏。我们将涵盖以下内容: 程序架构–逻辑部分和界面部分 游戏规则–双方玩家如何落子 代码实现–包括棋盘绘制、棋子判定、游戏结果输出等功能 1. 程序架构 五子棋小游戏的程序一般分为两个部分,逻辑部分和界面部分。逻辑部分处理游戏规则,包括落子,判断输赢等。界面部分负责与用户交互,…

    C 2023年5月23日
    00
  • 一起来学习C语言的程序环境与预处理

    让我来详细讲解一下“一起来学习C语言的程序环境与预处理”的完整攻略。 程序环境的搭建 安装编译器 首先,我们需要选择一款适合自己的C语言编译器。常见的编译器有: GCC:开源免费的编译器,支持多种操作系统,功能强大。 MSVC:微软公司开发的编译器,适合在Windows操作系统上使用。 Clang:基于LLVM架构的编译器,支持各种操作系统,编译速度快。 在…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部