数据结构和算法—顺序表

顺序表是简单的一种线性结构,逻辑上相邻的数据在计算机内的存储位置也是相邻的,可以
快速定位第几个元素,中间不允许有空值,插入、删除时需要移动大量元素。

顺序表的三个要素:
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大佬!

发布了18 篇原创文章 · 获赞 2 · 访问量 231

猜你喜欢

转载自blog.csdn.net/weixin_44238530/article/details/102557352