初步学习数据结构时,可以通过C语言实现顺序表的基本操作。如分别通过静态分配与动态分配初始化,以及线性表中数据元素的插入、删除、按值查找与按位查找。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define dynamic_allocation //static_ /dynamic_
/*顺序表的实现:静态分配*/
#ifdef static_allocation
#define MaxSize 10 //定义最大长度
typedef struct{
int data[MaxSize]; //用静态“数组”存放数据元素
int length; //顺序表的当前长度
}SqList; //顺序表的类型定义:静态分配方式
/*初始化顺序表*/
void InitList(SqList *L) {
for (int i = 0; i < MaxSize; i++)
L->data[i] = 0; //将所有数据元素设置为默认初始值
L->length = 0; //顺序表初始长度为0
};
/*访问顺序表的数据元素*/
void accessList(SqList L) {
for (int i = 0; i < L.length; i++)//i < L.length
printf("data[%d]=%d\n", i, L.data[i]);
}
#endif // static_allocation
/*顺序表的实现:动态分配*/
#ifdef dynamic_allocation
#define InitSize 10 //默认的最大长度
typedef struct{
int *data; //指示动态分配数组的指针
int MaxSize; //顺序表的最大容量
int length; //顺序表的当前长度
}SeqList;
void InitList(SeqList *L) {
/*用malloc函数申请一片连续的存储空间*/
L->data = (int *)malloc(InitSize * sizeof(int));
L->length = 0;
L->MaxSize = InitSize;
}
/*增加动态数组的长度*/
void IncreaseSize(SeqList L, int len) {
int* p = L.data;
L.data = (int*)malloc((L.MaxSize + len) * sizeof(int));
for (int i = 0; i < L.length; i++) {
L.data[i] = p[i]; //将数据复制到新的区域
}
L.MaxSize = L.MaxSize + len;//顺序表最大长度增加len
free(p); //释放原来的内存空间
}
/*访问顺序表的数据元素*/
void accessList(SeqList L) {
for (int i = 0; i < L.length; i++)//i < L.length
printf("data[%d]=%d\n", i, L.data[i]);
}
#endif // dynamic_allocation
/*顺序表的基本操作:插入*/
bool ListInsert(SeqList *L, int i, int e) {
if (i<1 || i>(L->length + 1)) //判断i的范围是否有效
return false;
if((L->length)>= InitSize) //存储空间已满,不能插入。动态分配上限值InitSize,静态上限值MaxSize
return false;
for (int j = L->length; j >= i; j--) //将第i个元素及之后的元素后移
L->data[j] = L->data[j - 1];
L->data[i - 1] = e; //在位置i处放入e
L->length++; //长度加1
return true;
}
/*顺序表的基本操作:删除*/
bool ListDelete(SeqList* L, int i, int *e) {
if (i<1 || i>(L->length)) //判断i的范围是否有效
return false;
*e = L->data[i - 1]; //将被删除的元素赋值给e
for (int j = i; j < L->length; j++) //将第i个元素后的元素前移
L->data[j-1] = L->data[j];
L->length--; //长度减1
return true;
}
/*顺序表的基本操作:按位查找*/
int GetElem(SeqList* L, int i) {
return L->data[i - 1];
}
/*顺序表的基本操作:按值查找*/
int LocateElem(SeqList* L, int e) {
for (int i=0; i < L->length; i++)
if (L->data[i] == e)
return i + 1; //数组下标为i的元素值等于e,返回其位序i+1
return 0; //退出循环,说明查找失败
}
int main() {
/*顺序表声明与初始化*/
#ifdef static_allocation
SqList L; //声明一个顺序表
InitList(&L); //初始化顺序表
#endif // static_allocation
#ifdef dynamic_allocation
SeqList L;
InitList(&L);
IncreaseSize(L,5); //扩大动态分配的内存长度
#endif // dynamic_allocation
/*顺序表的基本操作:插入*/
L.data[0] = 10;
L.data[1] = 11;
L.data[2] = 12;
L.data[3] = 13;
L.data[4] = 14;
L.length = 5;
ListInsert(&L, 3, 3);
/*顺序表的基本操作:删除*/
int e = -1; //用变量e把删除的元素“带回来”
if (ListDelete(&L, 3, &e))
printf("\n已删除第3个元素,删除元素值为=%d\n", e);
else
printf("\n位序i不合法,删除失败\n");
/*顺序表的基本操作:按位查找*/
printf("\n按位查找已完成,第3个元素值为=%d\n", GetElem(&L, 3));
/*顺序表的基本操作:按值查找*/
int t = 11;
if (LocateElem(& L, t))
printf("\n按值查找已完成,第%d个元素值为t \n", LocateElem(&L, t),t);
else
printf("\n%d不存在,查找失败\n",t);
/*访问顺序表*/
accessList(L);
return 0;
}
在学习中遇到的问题:
C语言无法实现cpp通过(&x)将函数参数值返回到main函数。当初始化线性表时,如果通过函数进行初始化,会报错:使用了未初始化的局部变量
方法1:在声明顺序表时修改为“SqList L={0}”,不再报错,但仍存在警告:使用了未初始化的内存
方法2:直接在main函数中对顺序表进行初始化
方法3:将顺序表L变为全局变量
方法4:(即代码中的解决方法)使用指针对变量地址值进行传递
使用动态分配实现顺序表的存储,读取数据时引发异常
![](https://i-blog.csdnimg.cn/blog_migrate/d7934616142264830756888bee407ab9.png)
该问题的出现原因同问题1一样,是由于变量通过函数进行的初始化操作并没有跟随顺序表变量回到主函数中。解决办法同上。