数据结构-顺序表

目录

基本概念

顺序表的特点

部分函数算法分析

线性表的顺序表示和实现

global.h

SqList.h

SqListTest.cpp

运行结果


基本概念

  • 线性表是最常用且简单的一种数据结构,一个线性表是n个元素的有限序列
  • 线性结构:在数据元素的非空有限集合中,有以下几种特点:
存在唯一的一个被称作"第一个的元素"
存在唯一的一个被称作"最后一个的元素"
除第一个以外,集合中的每一个数据元素均只有一个前驱
除最后一个以外,集合中的每一个数据元素均只有一个后继

顺序表的特点

  • 顺序存储结构是一种随机存取的存储结构
  • 无需为表中的数据元素之间的逻辑关额外的存储空间
  • 能够快速的获取索引位置上的数据元素信息
  • 容易造成存储空间的碎片化

部分函数算法分析

  • 顺序表在指定索引位置插入数据元素
//顺序表在指定索引位置进行数据元素的插入
Status InsertSqList(SqList& L,int index,ElemType elem) {
	//判断插入索引位置是否合法
	if (index < 1 || index > L.length + 1) {
		cout << "插入索引位置不合法" << endl;
		return ERROR;
	}
	//判断顺序表是否已满
	if (L.length >= L.list_size) {
		//为顺序表扩容
		ElemType* newbase;
		newbase = (ElemType*)realloc(L.elem, (L.list_size + LIST_INCREMENT) * sizeof(ElemType));
		//判断扩容操作是否成功
		if (!newbase)
			exit(OVERFLOW);
		//将新分配的空间基地址赋值给顺序表
		L.elem = newbase;
		//顺序表空间增大
		L.list_size += LIST_INCREMENT;
	}
	//q位置为插入数据位置
	ElemType* q = &(L.elem[index - 1]);
	//将插入位置及其以后的所有元素后移一位
	for (ElemType* p = &(L.elem[L.length - 1]); p >= q; --p) {
		*(p + 1) = *p;
	}
	*q = elem;
	//存储的元素个数加一
	++L.length;
	return OK;
}

在插入数据前,应先判断插入的位置是否合法。因为顺序表空间是有限的,在插入数据前需要判断顺序表空间是否已满,是否需要扩容

顺序表的第一个数据元素的索引为0,所以在插入的位置索引为(index - 1),找到该位置后,需将插入位置即以后的所有元素都向后移动一位,从最后一个数据元素依次开始移动,直到到达插入位置元素移动,循环终止

  •  顺序表在指定索引位置上删除数据
//顺序表删除指定位置上的数据元素
Status DeleteSqList(SqList& L, int index) {
	//判断删除元素的索引位置是否合法
	if (index < 1 || index > L.length) {
		cout << "删除索引位置信息不合法" << endl;
		return ERROR;
	}
	//q位置为删除数据的位置
	ElemType* q = &(L.elem[index - 1]);
	ElemType* p = &(L.elem[L.length - 1]);
	//将q位置之后的数据元素向前移动一位
	for (++q; q <= p; ++q) {
		*(q - 1) = *q;
	}
	--L.length;
	return OK;
}

 先判断删除索引位置是否合法,即是否超出顺序表内存在的元素个数长度,是否小于1

找到删除位置的索引后,需将索引位置后的每一个元素都向前移动一个位置,即删除索引位置上的数据信息被后一个覆盖,注意:最后一个元素(L.elem[L.length - 1])仍然存在顺序表内,没有被覆盖,但是顺序表内已存在的元素长度(L.length - 1),所以在遍历的时候不会遍历到该数据元素


线性表的顺序表示和实现

  • global.h
  • SqList.h
  • SqListTest.cpp

global.h

相关头文件的引用,以及相应全局变量、常量的声明

#pragma once

#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>

using namespace std;

#define TRUE 1

#define FALSE 0

#define OK 1

#define ERROR 0

#define INFEASIBLE -1

#define EQ(a,b) ((a) == (b))

#define LT(a,b) ((a) < (b))

#define LQ(a,b) ((a) <= (b))

#define MT(a,b) ((a) > (b))

#define MQ(a,b) ((a) >= (b))

typedef int Status;

SqList.h

顺序表的结构定义,以及顺序表的相关操作算法

#pragma once
#include"global.h"

/*----------线性表的动态分配顺序存储结构----------*/

//线性表初始空间分配的大小
#define LIST_INIT_SIZE 100

//空间扩展的分配增量
#define LIST_INCREMENT 10

//自定义的元素类型
#define ElemType int

//定义线性表
typedef struct SqList {
	//数据存储空间基地址
	ElemType* elem;
	//顺序表内存在的元素个数
	int length;
	//当前顺序表的存储空间大小
	int list_size;
}SqList;

//顺序表的初始化(操作成功返回OK)
Status InitSqList(SqList& L) {
	//为线性表分配100*sizeof(ElemType)空间大小
	L.elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
	//判断空间分配是否成功
	if (!L.elem)
		exit(OVERFLOW);
	//为初始顺序表的length、与list_size赋值
	L.length = 0;
	L.list_size = 100;
	return OK;
}

//顺序表的遍历
void ShowSqList(SqList L) {
	for (int i = 0; i < L.length; i++) {
		cout << L.elem[i] << " ";
 	}
	cout << endl;
}

//顺序表数据元素的顺序添加
Status AddSqList(SqList& L,ElemType elem) {
	//判断顺序表是否已满
	if (L.length >= L.list_size) {
		//为顺序表扩容
		ElemType* newbase;
		newbase = (ElemType*)realloc(L.elem, (L.list_size + LIST_INCREMENT) * sizeof(ElemType));
		//判断扩容操作是否成功
		if (!newbase)
			exit(OVERFLOW);
		//将新分配的空间基地址赋值给顺序表
		L.elem = newbase;
		//顺序表空间增大
		L.list_size += LIST_INCREMENT;
	}
	//将数据按顺序添加至顺序表中
	L.elem[L.length++] = elem;
	return OK;
}

//顺序表在指定索引位置进行数据元素的插入
Status InsertSqList(SqList& L,int index,ElemType elem) {
	//判断插入索引位置是否合法
	if (index < 1 || index > L.length + 1) {
		cout << "插入索引位置不合法" << endl;
		return ERROR;
	}
	//判断顺序表是否已满
	if (L.length >= L.list_size) {
		//为顺序表扩容
		ElemType* newbase;
		newbase = (ElemType*)realloc(L.elem, (L.list_size + LIST_INCREMENT) * sizeof(ElemType));
		//判断扩容操作是否成功
		if (!newbase)
			exit(OVERFLOW);
		//将新分配的空间基地址赋值给顺序表
		L.elem = newbase;
		//顺序表空间增大
		L.list_size += LIST_INCREMENT;
	}
	//q位置为插入数据位置
	ElemType* q = &(L.elem[index - 1]);
	//将插入位置及其以后的所有元素后移一位
	for (ElemType* p = &(L.elem[L.length - 1]); p >= q; --p) {
		*(p + 1) = *p;
	}
	*q = elem;
	//存储的元素个数加一
	++L.length;
	return OK;
}

//顺序表删除指定位置上的数据元素
Status DeleteSqList(SqList& L, int index) {
	//判断删除元素的索引位置是否合法
	if (index < 1 || index > L.length) {
		cout << "删除索引位置信息不合法" << endl;
		return ERROR;
	}
	//q位置为删除数据的位置
	ElemType* q = &(L.elem[index - 1]);
	ElemType* p = &(L.elem[L.length - 1]);
	//将q位置之后的数据元素向前移动一位
	for (++q; q <= p; ++q) {
		*(q - 1) = *q;
	}
	--L.length;
	return OK;
}

SqListTest.cpp

#include"SqList.h"

int main() {
	SqList list;
	InitSqList(list);
	int count = 0;
	cout << "为顺序表添加多少数据元素:" << endl;
	cin >> count;
	cout << "请输入" << count << "个数据元素:" << endl;
	ElemType elem;
	for (int i = 0; i < count; i++) {
		cin >> elem;
		AddSqList(list, elem);
	}
	ShowSqList(list);
	cout << "----------数据插入操作----------" << endl;
	cout << "请输入插入索引位置:" << endl;
	int index = 0;
	cin >> index;
	cout << "请输入插入的数据元素:" << endl;
	cin >> elem;
	InsertSqList(list, index, elem);
	ShowSqList(list);
	cout << "----------数据删除操作----------" << endl;
	cout << "请输入删除索引位置:" << endl;
	cin >> index;
	DeleteSqList(list, index);
	ShowSqList(list);
}

运行结果

为顺序表添加多少数据元素:
5
请输入5个数据元素:
12 23 34 54 56
12 23 34 54 56
----------数据插入操作----------
请输入插入索引位置:
3
请输入插入的数据元素:
44
12 23 44 34 54 56
----------数据删除操作----------
请输入删除索引位置:
2
12 44 34 54 56

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值