数据结构与算法学习笔记(一)-----顺序表

前言

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


一、顺序表的三个要素:

1.存储位置的基地址(elems)
2.实际元素个数,即顺序表的长度(length)
3.一段连续的存储空间(size)

如下图:
在这里插入图片描述

二、顺序表结构体定义及初始化

结构体的定义:

#define MAX_SIZE 100

typedef struct
{
	ElemType *elems;	// 顺序表的基地址(ElemType为要存储的数据类型)
	int length;			//顺序表的长度
	int size;			//顺序表总的空间大小
}Sqlist;

初始化:

bool initSqlist(Sqlist& L)	//初始化顺序表(构造一个空的存储int类型数据的顺序表)
{
	L.elems = new int[MAX_SIZE];	//分配 MAX_SIZE 的空间
	if (!L.elems)		//若动态内存分配失败,返回false,初始化失败
	{
		return false;
	}
	else
	{
		L.length = 0;		//空表的表长为0
		L.size = MAX_SIZE;
		return true;
	}
}

三、顺序表的"增、插、删、销"

增:给空表添加元素
插:在表中插入新的元素
删:删除表中元素
销:销毁顺序表

1.给空表添加元素

在这里插入图片描述
将元素添加到表尾:

bool listAppend(Sqlist& L, int e)	//顺序表增加元素,e代表增加的元素
{
	if (L.length == MAX_SIZE)		//顺序表已满,无法在尾部添加元素
	{
		return false;
	}
	else
	{
		L.elems[L.length] = e;		//将元素添加到表尾
		L.length++;					//每填一个元素,表长都要加1
		return true;
	}
	cout << endl;
}

2.在表中插入新的元素

在这里插入图片描述
我们在元素"1"的位置插入元素"3"时,元素"2"先向下移动一个单位,然后元素"1"再向下移动一个位置(此时元素"1"在元素"2"移动之前的位置),最后,元素"3"再插入元素"1"移动之前的位置,这样就完成了插入新元素,每插入一个元素,表长加1(如果要在顺序表结尾插入数据,可以写一个尾插函数或者转换成在表尾添加元素进行操作)

bool listInsert(Sqlist& L, int i, int e)	//i代表元素插入位置,e代表插入的元素
{
	if (i < 0 || i >= L.length)		//插入位置不合法
	{
		return false;
	}
	else if (L.length == MAX_SIZE)		//存储空间已满,无法插入
	{
		return false;
	}
	else	
	{
		for (int j = L.length-1; j >= i; j--)
		{
			L.elems[j + 1] = L.elems[j];	//元素后移,为新元素让出位置(越靠近表尾越先移动)
		}
		L.elems[i] = e;		//元素插入
		L.length++;		//每插入一个元素,表长都要加1
		return true;
	}
}

3.删除表中元素

在这里插入图片描述
我们删除元素"1"时,可以直接让元素"2"向上移动一个单位,让元素"2"覆盖元素"1",然后元素"3"再向上移动一个单位,最后元素"4"向上移动一个单位,就完成了删除操作,每删除一个元素,表长减1(如果删除元素在表尾,直接让表长减1即可)

bool listDelete(Sqlist& L, int i)		//删除元素,i代表删除元素的下角标
{
	if (i < 0 || i >= L.length)		//i值不合法,删除失败,返回false
	{
		return false;
	}
	else if (i == L.length - 1)		//删除元素在表尾,表长直接减1
	{
		L.length--;
		return false;
	}
	else		
	{
		for (int j = i; j < L.length; j++)
		{
			L.elems[j] = L.elems[j + 1];//在表中删除元素,直接用j+1的值覆盖j的值即可
		}
		L.length--;		//每删除一个元素,表长都要减1
		return true;
	}
}

4.销毁顺序表

我们在初始化顺序表时,给它分配了一块MAX_SIZE大小的内存用来存储数据,所以销毁顺序表时,只需释放掉这块内存即可

void listDestory(Sqlist& L)
{
	cout << "销毁顺序表销毁..." << endl;
	if (L.elems)
	{
		delete []L.elems;		//释放内存
	}
	L.length = 0;
	L.size = 0;
}

四、源码

#include <iostream>
#include <Windows.h>

#define MAX_SIZE 100

using namespace std;

typedef struct		//构建顺序表
{		
	int* elems;			//顺序表元素
	int length;			//顺序表长度
	int size;			//顺序表大小
}Sqlist;

bool initSqlist(Sqlist& L)		//初始化顺序表
{
	L.elems = new int[MAX_SIZE];
	if (!L.elems)				//动态内存分配失败
	{
		return false;
	}
	else
	{
		L.length = 0;
		L.size = MAX_SIZE;
		return true;
	}
}

bool listAppend(Sqlist& L, int e)	//顺序表增加元素,e代表增加的元素
{
	if (L.length == MAX_SIZE)		//顺序表已满,无法在尾部添加元素
	{
		return false;
	}
	else
	{
		L.elems[L.length] = e;
		L.length++;
		return true;
	}
	cout << endl;
}

bool listInsert(Sqlist& L, int i, int e)	//i代表元素插入位置,e代表插入的元素
{
	if (i < 0 || i >= L.length)		//插入位置不合法
	{
		return false;
	}
	else if (L.length == MAX_SIZE)		//存储空间已满,无法插入
	{
		return false;
	}
	else
	{
		for (int j = L.length-1; j >= i; j--)
		{
			L.elems[j + 1] = L.elems[j];
		}
		L.elems[i] = e;
		L.length++;
		return true;
	}
}

bool listDelete(Sqlist& L, int i)		//删除元素,i代表删除元素的下角标
{
	if (i < 0 || i >= L.length)		//i值不合法,删除失败
	{
		return false;
	}
	else if (i == L.length - 1)
	{
		L.length--;
		return true;
	}
	else
	{
		for (int j = i; j < L.length; j++)
		{
			L.elems[j] = L.elems[j + 1];
		}
		L.length--;
		return true;
	}
}

void listDestory(Sqlist& L)
{
	cout << "销毁顺序表销毁..." << endl;
	if (L.elems)
	{
		delete []L.elems;
	}
	L.length = 0;
	L.size = 0;
}

void listPrint(Sqlist& L)		//打印顺序表信息
{
	cout << endl;
	cout << "顺序表内存大小 size= " << L.size
		<< ", 已保存元素个数 length= " << L.length << endl;
	cout << "顺序表中元素:";
	for (int j = 0; j <= L.length - 1; j++)
	{
		cout << L.elems[j] << " ";
	}
	cout << endl << endl;
}

int main()
{
	Sqlist L;
	int i;
	int e;
	int count;
	cout << "顺序表初始化..." << endl;
	if (initSqlist(L))
	{
		cout << "顺序表初始化成功!" << endl;
		cout << "请输入要添加的元素个数:";
		cin >> count;
		for (int i = 0; i < count; i++)
		{
			cout << "请输入要添加的元素:";
			cin >> e;
			if (listAppend(L, e))
			{
				cout << "添加成功!" << endl;
			}
			else
			{
				cout << "添加失败!" << endl;
			}
		}
		listPrint(L);
		cout << "请输入插入元素的位置:";
		cin >> i;
		cout << "请输入插入的元素:";
		cin >> e;
		if (listInsert(L, i, e))
		{
			cout << "插入成功!" << endl;
		}
		else
		{
			cout << "插入失败!" << endl;
		}
		listPrint(L);
		cout << "请输入删除元素的角标:";
		cin >> i;
		if (listDelete(L, i))
		{
			cout << "删除成功!" << endl;
		}
		else
		{
			cout << "删除失败!" << endl;
		}
		listPrint(L);
		listDestory(L);
	}
	else
	{
		cout << "顺序表初始化失败!" << endl;
	}
	listPrint(L);

	system("pause");
	return 0;
}

五、运行结果

在这里插入图片描述


总结

以上便是对顺序表的学习总结,如有误处,请各位指正!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值