数据结构(C++):顺序表模板

一、顺序表的概念

        顺序表是一种线性的数据结构,又属于线性表的一种,其中数据元素按照特定顺序依次存储在连续的内空间中,它由一系列元素组成,每一个元素都与唯一索引(下标)相关联,索引从0开始递增。

二、顺序表的搭建

       先用#definev eletype  数据类型,这样便于修改变量的数据类型;然后定义一个结构体(struct sequentialList ),在结构体中,先定义一个指针(eletype* elements),用于存储顺序表的元素,再定义一个顺序表的存储元素个数(int size),和顺序表的容量(int capacity),顺序表实际容量 size<=capacity;

#include<iostream>
using namespace std;

#define eletype int

struct sequentialList {
	eletype* elements;//存储的数组,用指针表示
	int size;//顺序表中元素个数
	int capacity;//顺序表实际容量 size<=capacity
};

        然后进行一个初始化,为结构体中的变量进行赋初值;

void intializeList(sequentialList* list, int capacity) {
	list->elements = new eletype[capacity];//为elements申请capacity个空间
	list->size = 0;
	list->capacity = capacity;
}

        再进行顺序表的销毁

void distroyList(sequentialList* list) {

	delete[] list->elements;
}

        获取元素个数接口(获取顺序表大小)

int size(sequentialList* list) {
	return list->size;

}

        以及最后判断顺序表是否为空

//判断顺序表是否为空

bool isEmpty(sequentialList* list) {
	return list->size == 0;

}

三、顺序表的组成

        所有的数据结构都由增删改查四个部分组成。

1、顺序表的元素插入

        顺序表的元素插入,就是按照给定索引和一个元素,将这个元素插入到对应的索引位置上,这个位置以后的元素都要往后移动一个位置。

        元素插入步骤:

        第一步:判断插入位置是否合法(throw std::invalid_argument("Invalid index")),不合法就抛出异常(例如:原本只有5个元素,给定的索引是10,或者是给定下标小于0,那么给定的位置就是不合法的);
//1、判断插入位置是否合法

	if (index<0 || index>list->size) {
		throw std::invalid_argument("Invalid index");//抛出异常;表示下标非法
	}
        第二步:如果顺序表位置已满,那么就需要扩容顺序表,将原来的顺序表的容量进行倍增,要注意的是,进行完扩容后,要将原来空间中的元素重新赋给新的空间,并将原来空间内存进行销毁(delete[]);
//2、当顺序表空间用完之后,进行扩容

	if (list->size == list->capacity) {
		int newcapacity = list->capacity * 2;//定义一个新的空间为原来空间的两倍
		eletype* newelements = new eletype[newcapacity];//将新定义的空间赋给一个新的指针
		//将原来数组中元素赋给新的数组
		for (int i = 0; i < list->size; ++i) {
			newelements[i]=list->elements[i];
		}
		delete[] list->elements;//将原来数组内存删除
		list->capacity = newcapacity;
		list->elements = newelements;
	}
        第三步:将插入位置之后的元素往后移动,为新元素腾出空间,要注意的是(插入时是从最后一个位置往前遍历,并且将后一个元素传递给前一个位置);
//插入元素

	for (int i = list->size; i > index; i--) {
		list->elements[i] = list->elements[i - 1];
	}
        第四步:将新元素插到指定位置;
list->elements[index] = element;
        第五步:更新顺序表的大小,顺序表大小加一。
list->size++;

2、元素的删除

        顺序表的元素删除,就是指定一个索引,将这个索引上的元素删除,并且把这个索引位置后面的所有元素都往前移动一个位置。

        元素删除步骤:

        第一步:与元素的插入相同都需要进行判断位置是否合法,这里判断的是删除位置是否合法,与元素插入不同的是,删除所判断的位置区间为0到size-1,当位置为size时元素不存在;
//判断删除位置是否合法

	if (index<0 || index>=list->size) {//0到list->size-1为数组空间,当index为list->size时元素不存在
		throw std::invalid_argument("Invalid index");//抛出异常;表示下标非法
	}
        第二步:当删除位置为最后一个位置时,直接将顺序表的大小减一;
        第三步:如果删除位置不是最后一个元素,将删除位置之后的元素向前移动,覆盖要删除的元素;
//删除元素

	for (int i = index; i < list->size - 1; ++i) {
		list->elements[i] = list->elements[i + 1];
	}
	list->size--;
        第四步:更新顺序表的大小。

3、元素的查找

        顺序表的元素查找是指在顺序表中查找指定元素是否存在,如果存在则返回该元素索引,否则返回-1。

        查找步骤:

       第一步:遍历整个顺序表,对顺序表中每个元素,和指定元素进行比较,如果相同则返回当前索引;
for (int i = 0; i < list->size; ++i) {
		if (list->elements[i] == element) {
			return i;
		}
	}
        第二步:如果遍历完整个顺序表元素都没有找到相同元素,便返回-1(return-1;)。

4、元素的索引

        顺序表的元素索引,是指给定一个索引值,通过下标访问,直接在顺序表中获取元素的值。

        索引的步骤只有一步:直接通过索引访问即可得到对应的元素,但是在索引访问前要进行判断是否合法,和删除操作相同。
eletype getElemnets(sequentialList* list, int index) {
	//判断索引位置是否合法

	if (index < 0 || index >= list->size) {//0到list->size-1为数组空间,当index为list->size时元素不存在
		throw std::invalid_argument("Invalid index");//抛出异常;表示下标非法
	}
	return list->elements[index];
}

5、元素的修改

        顺序表的元素修改是指将顺序表中指定元素更新为新的值。

        修改步骤与索引步骤相同都需要进行判断位置是否合法,然后直接通过索引访问即可得到对应元素,修改成指定的值。

void updateElement(sequentialList* list, int index, eletype value) {
	//判断修改位置是否合法

	if (index < 0 || index >= list->size) {//0到list->size-1为数组空间,当index为list->size时元素不存在
		throw std::invalid_argument("Invalid index");//抛出异常;表示下标非法
	}
	list->elements[index] = value;//修改值
}

  四、顺序表的使用

int main() {
	sequentialList mylist;
	intializeList(&mylist, 10);
	for (int i = 0; i < 10; ++i) {
		insert(&mylist, i, i * 10);
	}
	cout << "size: " << size(&mylist) << endl;
	cout << "is empty: " << isEmpty(&mylist) << endl;
	//元素索引
	for (int i = 0; i < size(&mylist); ++i) {
		//元素插入
		cout << getElemnets(&mylist, i)<<" ";
	}
	cout << endl;
	//元素修改
	int idx = findElement(&mylist, 20);
	updateElement(&mylist,idx, 21);
	for (int i = 0; i < size(&mylist); ++i) {
		cout << getElemnets(&mylist, i)<<" ";
	}
	cout << endl;
	//元素删除
	deleteElement(&mylist, 3);//删除索引为3上的数:30
	updateElement(&mylist, 1, 12);
	for (int i = 0; i < size(&mylist); ++i) {
		cout << getElemnets(&mylist, i) << " ";
	}
	cout << endl;
	distroyList(&mylist);//销毁顺序表
	return 0;
}

   

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值