学习目标:
- 动态顺序表的设计和实现
- 菜单实现
学习内容:
一、静态顺序表的缺点
//静态顺序表设计(固定大小)
//问题:给少了不够用,给多了用不完浪费,不能灵活控制
struct SeqList
{
int a[10];//定长的数组
int size;//有效数据的个数
};
typedef int SLDataType; //便于修改数据的类型int,从而达到存储不同类型的数
#define MAX_SIZE 10 //便于修改a数组的大小
struct SeqList
{
SLDataType a[MAX_SIZE];
int size;
};
void SeqListInit(SL s)//传值调用,应该用传址
{
memset(s.a, 0, sizeof(SLDataType)*MAX_SIZE);//对固定大小10个元素的数组初始化
s.size = 0;
}
void SeqListPushBack(SL* ps, SLDataType x)
{
if (ps->size == MAX_SIZE)
{
printf("SeqList is Full\n");
return;
}
ps->a[ps->size] = x;
ps->size++;
}
二、动态顺序表头文件
#define _CRT_SECURE_NO_WARNINGS 1
//#pragma once //防止被重复包含
//顺序表,有效数据在数组中的存储必须是连续的
#ifndef __SEQLIST__H__
#define __SEQLIST__H__
//动态顺序表设计(大小可变)
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDataType; //便于修改数据的类型int,从而达到存储不同类型的数
typedef struct SeqList
{
SLDataType* a;//指针变量a指向动态开辟的数组(空间),用来动态存放SLDataType类型的数据
int size;//有效数据的个数
int capacity;//容量空间的大小
}SL,SeqList;
//1、初始化
void SeqListInit(SL* ps);
//2、尾插
void SeqListPushBack(SL* ps, SLDataType x);
//空间销毁
void SeqListDestory(SL* ps);
//3、打印
void SeqListPrint(SL* ps);
//4、尾删
void SeqListPopBack(SL* ps);
//5、头插
void SeqListPushFront(SL* ps, SLDataType x);
//6、检查容量
void SeqListCheckCapacity(SL* ps);
//7、头删
void SeqListPopFront(SL* ps);
//8、任意位置插入
void SeqListInsert(SL* ps, int pos, SLDataType x);
//9、任意位置删除
void SeqListErase(SL* ps, int pos);
//10、顺序表查找
int SeqListFind(SL* ps, SLDataType x);//返回找到的数的下标
//...
//int SeqListSort(SL* ps, SLDataType x);//排序
//int SeqListBinaryFind(SL* psl, SLDataType x);//二分查找
//11、顺序表修改
void SeqListModify(SL* ps, int pos, SLDataType x);
#endif
三、代码逻辑分析与实现
1、void SeqListInit(SL* ps);动态顺序表初始化
//传值调用
void SeqListInit(SL s)
{
/*
//方法一:
s.size = 0;
s.a = NULL;
s.capacity = 0;//由于a指向的空间没有,容量即为0
*/
//方法二:
s.a = (SLDataType*)malloc(sizeof(SLDataType) * 4);//开辟四个SLDataType类型的空间大小
if (s.a == NULL)
{
printf("申请内存失败\n");
exit(-1);//结束程序
}
s.size = 0;
s.capacity = 4;//容量为存储类型的个数
}
void test()
{
SeqList s;
SeqListInit(s);
}
解读:
调用test函数测试,SeqListInit()的功能。在SeqListInit(s)处,按F9打断点,按F5直接运行到断点处,按F11进入函数内部。
注意:当如果不能进入函数,强制进入,可以在函数内部打一个断点,再进入。
分析:
SeqListInit(s);函数中SL s形参,是test函数的局部变量s的临时拷贝,即形参s和实参s(test函数的局部变量s)内容相同,但是各自位于不同的地址空间,形参的改变(空间的内容改变)不会影响实参的改变(空间的内容改变)。
解决方法:将实参的地址传递给形参,即传址调用
void SeqListInit(SL* ps)//传址调用
{
//方法1:
/*
ps->size = 0;
ps->a = NULL;
ps->capacity = 0;//由于a指向的空间没有,容量即为0
*/
//方法2:
ps->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);//一开始就开辟4个连续大小的空间
if (ps->a == NULL)
{
printf("申请内存失败\n");
exit(-1);
}
ps->size = 0;
ps->capacity =