这学期学校开设了数据结构与算法,为帮助更多小伙伴和巩固学习,我开始整理这门课的学习内容,希望能给同样在学习这门课的小伙伴们提供一些浅薄的思路。
目录
前言
正文部分
什么是线性表
整体思路
整体设计
顺序表结构体以及状态码类型创建
实现线性表的“创删查改”功能
完整代码
main.c
LinearList.c
LinearList.h
线性表(linear_list)是最常用且最简单的一种数据结构。线性表在内存中的布局和数组一样,都是连续的 。因此和链表相比,线性表的创建比链表更加容易,理解起来也更加易懂。
在开始设计线性表整体程序之前,我们首先需要进行思路整理,可以创建一个main.c文件来存放主函数,创建LinearList.c文件用于存放线性表相关函数,创建LinearList.h文件用于存放线性表相关结构体声明、函数声明、状态码。
可以参考以下顺序表结构体与状态类型来进行设计
//顺序表的数据结构体
typedef struct Dat {
int i;
}Dat;
//顺序表结构体
typedef struct SqList {
Dat* listDat; //顺序表数据的地址
int Length; //顺序表长度
}SqList;
typedef int Status; //状态码类型
//所需要的状态码
#define INIT_SUCCEED 1 //状态码:初始化成功
#define DESTORY_SUCCEED 1 //状态码:销毁成功
#define SUCCEED 1 //状态码:成功
#define ERROR_LENGTH 0 //状态码:错误的长度
在LinearList.c文件中编写如下代码,记得创建完成后在LinearList.h文件中写下该函数的函数声明。
/************************************************
函数名称:顺序表初始化函数
函数介绍:创建一个新的指定大小的顺序表,并赋初值0
函数参数:SqList *list -- 要创建的顺序表的地址
int length -- 要新建的顺序表的长度
返回类型:Status -- 状态类型
INIT_SUCCEED -- 1
************************************************/
Status InitList(SqList* list,int length)
{
//创建线性表
list->listDat = (Dat*)malloc(sizeof(Dat) * length);
list->Length = length;
//赋初值
for (int i = 0; i < list->Length; i++)
{
((list->listDat) + i)->i = 0;
}
return INIT_SUCCEED;
}
在创建线性表时我使用了动态内存分配的方法,先在内存中开辟一块所需要的线性表的空间,将这块空间强制类型转换为 Dat* 类型(可理解为Dat类型的数组),并将其首地址赋给 SqList结构体的成员变量 listDat 。在赋初值时,也使用了下标偏移的方法(第一个 i 为偏移量,第二个 i 为 Dat 结构体中的成员变量)。
销毁该线性表时,只需要将这块内存空间 free 并将 list->Length 赋为0即可。
/************************************************
函数名称:顺序表销毁函数
函数介绍:销毁指定的顺序表
函数参数:SqList *list -- 要销毁的顺序表的地址
返回类型:Status -- 状态类型
INIT_SUCCEED -- 1
************************************************/
Status DestoryList(SqList* list)
{
free(list->listDat);
list->Length = 0;
return DESTORY_SUCCEED;
}
/************************************************
函数名称:顺序表查看函数
函数介绍:查看顺序表的指定位置
函数参数:SqList *list -- 要查看的顺序表的地址
int n -- 要查看的值的下标(从0开始)
返回类型:Dat* dat -- 数据结构体的地址
特别的,若查找错误则返回NULL
************************************************/
Dat* FindList(SqList* list, int n)
{
if (n<0 || n>list->Length)
{
return NULL;
}
else
{
return (list->listDat + n);
}
}
这里返回的为顺序表指定位置的数据域的地址(Dat*类型),返回时也使用了下标偏移的方法。
/************************************************
函数名称:顺序表赋值函数
函数介绍:对指定顺序表的指定位置赋值
函数参数:SqList *list -- 要赋值的顺序表的地址
int n -- 要赋的值的下标(从0开始)
Dat dat -- 要赋的值的结构体
返回类型:Status -- 状态类型
SUCCEEED -- 1
ERROR_LENGTH -- 0
************************************************/
Status InputElem(SqList* list, int n,Dat dat) {
if (n<0 || n>list->Length)
{
return ERROR_LENGTH;
}
else
{
(list->listDat + n)->i = dat.i;
return SUCCEED;
}
}
以上就已经把这四个函数写完了。
开始在主函数中验证以上代码。
#include
#include "LinearList.h"
void main()
{
//创建顺序表
SqList myList;
(void)InitList(&myList, 6);
//链表赋值
Dat dat = { 4 };
InputElem(&myList, 2, dat);
//查看顺序表值
Dat* datGet = FindList(&myList, 2);
//输出值
printf("%d", datGet->i);
//销毁顺序表
(void)DestoryList(&myList);
}
运行后发现没有问题。
#include
#include "LinearList.h"
void main()
{
//创建顺序表
SqList myList;
(void)InitList(&myList, 6);
//链表赋值
Dat dat = { 4 };
InputElem(&myList, 2, dat);
//查看顺序表值
Dat* datGet = FindList(&myList, 2);
//输出值
printf("%d", datGet->i);
//销毁顺序表
(void)DestoryList(&myList);
}
#include "LinearList.h"
/************************************************
函数名称:顺序表初始化函数
函数介绍:创建一个新的指定大小的顺序表,并赋初值0
函数参数:SqList *list -- 要创建的顺序表的地址
int length -- 要新建的顺序表的长度
返回类型:Status -- 状态类型
INIT_SUCCEED -- 1
************************************************/
Status InitList(SqList* list,int length)
{
list->listDat = (Dat*)malloc(sizeof(Dat) * length);
list->Length = length;
for (int i = 0; i < list->Length; i++)
{
((list->listDat) + i)->i = 0;
}
return INIT_SUCCEED;
}
/************************************************
函数名称:顺序表销毁函数
函数介绍:销毁指定的顺序表
函数参数:SqList *list -- 要销毁的顺序表的地址
返回类型:Status -- 状态类型
INIT_SUCCEED -- 1
************************************************/
Status DestoryList(SqList* list)
{
free(list->listDat);
list->Length = 0;
return DESTORY_SUCCEED;
}
/************************************************
函数名称:顺序表赋值函数
函数介绍:对指定顺序表的指定位置赋值
函数参数:SqList *list -- 要赋值的顺序表的地址
int n -- 要赋的值的下标(从0开始)
Dat dat -- 要赋的值的结构体
返回类型:Status -- 状态类型
SUCCEEED -- 1
ERROR_LENGTH -- 0
************************************************/
Status InputElem(SqList* list, int n,Dat dat) {
if (n<0 || n>list->Length)
{
return ERROR_LENGTH;
}
else
{
(list->listDat + n)->i = dat.i;
return SUCCEED;
}
}
/************************************************
函数名称:顺序表查看函数
函数介绍:查看顺序表的指定位置
函数参数:SqList *list -- 要查看的顺序表的地址
int n -- 要查看的值的下标(从0开始)
返回类型:Dat* dat -- 数据结构体的地址
特别的,若查找错误则返回NULL
************************************************/
Dat* FindList(SqList* list, int n)
{
if (n<0 || n>list->Length)
{
return NULL;
}
else
{
return (list->listDat + n);
}
}
#pragma once
#include
#define INIT_SUCCEED 1 //状态码:初始化成功
#define DESTORY_SUCCEED 1 //状态码:销毁成功
#define SUCCEED 1 //状态码:成功
#define ERROR_LENGTH 0 //状态码:错误的长度
typedef int Status; //状态码类型
//顺序表的数据结构体
typedef struct Dat {
int i;
}Dat;
//顺序表结构体
typedef struct SqList {
Dat* listDat; //顺序表数据的地址
int Length; //顺序表长度
}SqList;
//函数声明
Status InitList(SqList* list, int n); //顺序表初始化函数
Status DestoryList(SqList* list); //顺序表销毁函数
Status InputElem(SqList* list, int n, Dat dat); //顺序表赋值函数
Dat* FindList(SqList* list, int n); //顺序表查看函数