顺序表是简单的一种线性结构,逻辑上相邻的数据在计算机内的存储位置也是相邻的,可以
快速定位第几个元素,中间不允许有空值,插入、删除时需要移动大量元素。
顺序表的三个要素:
1. 用 elems 记录存储位置的基地址
2. 分配一段连续的存储空间 size
3. 用 length 记录实际的元素个数,即顺序表的长度
程序的“正确”性 可以使用以下俩种方法
防御性编程(Defensive programming)是防御式设计的一种具体体现,它是为了保证,对程序的不可预见的使用,不会造成程序功能上的损坏。它可以被看作是为了减少或消除墨菲定律效力的想法。防御式编程主要用于可能被滥用,恶作剧或无意地造成灾难性影响的程序上。
断言是编程术语,表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真,可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言。同样,程序投入运行后,最终用户在遇到问题时可以重新启用断言。
防御性编程就是能对错误的操作,做出对应的反应
顺序表的基本操作如下:
#include <stdio.h>
#include <iostream>
#include <Windows.h>
#define MAX_ELEM 100
typedef int ELEMTYPE;
// 顺序表的定义
typedef struct {
ELEMTYPE* elem; // 元素首地址
int length; // 元素的个数
int size; // 元素的空间大小
}SeqList;
// 初始化顺序表
bool initList(SeqList* sl) {
if(!sl) return false; // 合法性检查
sl->elem = new ELEMTYPE[MAX_ELEM];
sl->length = 0;
sl->size = MAX_ELEM;
return true;
}
// 顺序表插入(添加)元素
// i如果是默认值0, 就在顺序表尾部追加
bool listInsert(SeqList* sl, ELEMTYPE& e, int i=0) {
if(!sl || !sl->elem) return false;
if(sl->length>=sl->size) return false;
if(i == sl->length+1 || i == 0) { //i 等于 最后一个+1 或者默认值0, 直接添加到表中
sl->elem[sl->length] = e;
sl->length++;
return true;
}
// 判断i值合法性
if(i<1 || i>sl->length+1) return false;
for(int j=sl->length; j>i-1; j--) { // 元素后移,腾出插入位置
sl->elem[j] = sl->elem[j-1];
}
sl->elem[i-1] = e;
sl->length++;
return true;
}
// 顺序表删除元素
// i如果是默认值0, 就删除顺序表最后一个元素
bool listDelete(SeqList* sl, ELEMTYPE& e, int i=0) {
if(!sl || !sl->elem) return false; // 合法性检查
if(sl->length <= 0) return false; // 没有元素, 如何删除
if(i == sl->length || i == 0) {
e = sl->elem[sl->length-1];
sl->length--;
return true;
}
// 判断i值合法性
if(i<1 || i>sl->length) return false;
e = sl->elem[i-1];
for(int j = i-1; j<sl->length-1; j++) {
sl->elem[j] = sl->elem[j+1]; // 元素前移,实现删除
}
sl->length--;
return true;
}
// 顺序表的遍历
void listPrint(SeqList* sl) {
if(!sl || !sl->elem) return;
printf("长度为:%d, 空间为:%d\n", sl->length, sl->size);
printf("元素:");
for(int j = 0; j<=sl->length-1; j++) {
printf("%d ", sl->elem[j]);
}
printf("\n");
}
// 获取指定位置元素
// i如果为默认值0 返回首元素
bool getElem(SeqList* sl, ELEMTYPE& e, int i=0) {
if(!sl || !sl->elem) return false;
if((i == 0 || i == 1) && sl->length >= 1) {
e = sl->elem[0];
return true;
}
if(i<1 || i>sl->length) return false;
e = sl->elem[i-1];
return true;
}
// 获取顺序表的长度
int getLength(SeqList* sl) {
if(!sl || !sl->elem) return -1;
return sl->length;
}
// 顺序表的清空
bool listClear(SeqList* sl) {
if(!sl || !sl->elem) return false;
sl->length = 0;
return true;
}
// 顺序表的销毁
bool listDerstoy(SeqList* sl) {
if(!sl) return false;
if(sl->elem) delete[] sl->elem;
sl->length = 0;
sl->size = 0;
return true;
}
// 测试代码
int main(void) {
SeqList list;
ELEMTYPE date;
// 初始化顺序表
if(initList(&list)) {
printf("初始化成功\n");
}else {
printf("初始化失败\n");
system("pause");
exit(1);
}
//添加元素
for(int i = 0; i < 5; i++) {
printf("请输入元素的数据:");
scanf("%d", &date);
listInsert(&list, date);
}
listPrint(&list));
// 删除元素
if(listDelete(&list, date)) {
printf("删除数据成功, 数据为: %d\n", date);
}else {
printf("删除元素失败\n");
}
if(getElem(&list, date)) {
printf("获取元素成功, 元素为:%d\n", date);
} else {
printf("获取元素失败\n");
}
return 0;
}
本人购买于2019.3 不到3000,如今就不知了…
本人学习的课程
本文为本人的学习过程, 为了培养自己, 才写的博客, 有不足之处,欢迎各位大佬点评!致谢IT大佬!