数据结构 第三章 线性表(一)

🚀 写在最前:在前面两篇文章中,了解了数据结构到底在学什么以及知道了程序=数据结构+算法这个思想,了解了如何评价算法的五大特性,如何评价一个算法的好坏,以及两个评价指标的计算,而今天我们开始学习第一个数据结构。

🚀  :点个关注吧😀,让我们一起探索计算机的奥秘!

目录

🍟线性表的定义和基本操作

​编辑

🍟线性表的定义

 🍟线性表的操作

🍗🍗线性表的顺序存储(顺序表) 

🍗文件结构

🍗线性表的顺序存储——初始化

 🍗线性表的顺序存储——销毁

🍗线性表的顺序存储——求表长

🍗 线性表的顺序存储——判空

🍗线性表的顺序存储——插入

 🍗线性表的顺序存储——删除

 🍗线性表的顺序存储——按值查找

 🍗线性表的顺序存储——按位查找

 🍗线性表的顺序存储——打印列表


🍟线性表的定义和基本操作

首先先来看下在第一章中了解的一些数据结构的知识,逻辑结构面向我们人自己设计出来的抽象结构,物理结构面向计算机的存储系统,是逻辑结构实际存储在计算里的结构。

线性表属于逻辑结构,先来了解这个逻辑结构是什么样,这个逻辑结构具体在计算中的存储,在后面会学习到线性表的顺序存储(顺序表)、线性表的链式存储(链表)。

🍟线性表的定义

🚀🚀​​​​​​线性表的官方定义:线性表是具有相同数据类型的n个数据元素的有限序列,其中n为表长,若n为0,则此时线性表称为空表。简单理解就是把有限个相同类型的数据串成一个串就是线线性表,如下图所示,4个相同类型的数据串成一串成为一个线性表,对于线性表来说,除第一个元素外,每一个元素都有直接后继,除最后一个元素外,每一个元素都有直接前驱。

 🍟线性表的操作

定义好了一个数据类型——线性表,就必须为这种数据类型匹配上相关的操作。常见的就是以下几种操作

  • InitList(&L);  //初始化链表
  • DestoryList(&L);  //销毁列表
  • ListInsert(&L,i,e):  //插入操作,在列表第i位置上插入
  • ListDelete(&L,i,e):  //删除操作,在列表第i位置上删除
  • GetElem(L,i);  //按位查找,获取第i个位置上的元素
  • LocateElem(L,e);  //按值查找,获取元素e
  • Length(L);  //获取线性表的长度
  • PrintList(L);  //打印列表
  • Empty(L);  //判断线性表是否为空

🚀🚀至此,给出了线性表这个数据结构,以及这个数据结构的相关操作,接下去我们就得依次在计算机中来实现这些操作,需要注意的是,由于线性表这个数据结构是我们人为定义的逻辑结构,而这些逻辑具体在计算中存储方式的不同就会造成存储结构不同,从而对于数据结构的操作具体实现也会不同,下面看线性表在计算机中采用顺序存储,即简称顺序表它的一些操作实现


🍗🍗线性表的顺序存储(顺序表) 

如下图所示,就是一个线性表在计算机中的顺序存储,逻辑相邻,实际物理地址也相邻。

🍗文件结构

以下操作,都以静态分配内存为例 

🍗线性表的顺序存储——初始化

InitList(&L);  //初始化链表

LinerList.h中的内容,在这里实际定义数据结构以及数据结构的操作。

#pragma once
#include<stdio.h>
#include<stdlib.h>
#define maxsize 100
typedef int ElementType;  //重定义元素类型为ElementType

//定义线性表类型,使用静态分配内存
typedef struct StaticLinerList {
	ElementType data[maxsize];  //线性表的大小
	int length;                 //记录线性表的长度
}SLinerList;


//线性表的操作

//初始化线性表
void InitList(SLinerList &L);

 LinerList.c中的内容,在这里实际实现数据结构的操作

#include "LinerList.h"

//初始化线性表
void InitList(SLinerList& L) {
	L.length = 0;   //将线性表的长度置为空
}

test.c中的内容,测试实现的数据结构是否好用 

#include"LinerList.h"

int main() {
	SLinerList SL1;  //定义一个线性表SL1

	//将线性表SL1进行初始化操作
	InitList(SL1);

	printf("现在线性表的长度为%d", SL1.length);
	return 0;
}

测试结果:

现在线性表的长度为0

D:\C_WorkSpace\LinerList\x64\Debug\LinerList.exe (进程 20920)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

 🍗线性表的顺序存储——销毁

DestoryList(&L);  //销毁列表

LinerList.h中的内容

#pragma once
#include<stdio.h>
#include<stdlib.h>
#define maxsize 100
typedef int ElementType;  //重定义元素类型为ElementType

//定义线性表类型,使用静态分配内存
typedef struct StaticLinerList {
	ElementType data[maxsize];  //线性表的大小
	int length;                 //记录线性表的长度
}SLinerList;


//线性表的操作

//初始化线性表
void InitList(SLinerList &L);

//线性表的销毁
void DestroyList(SLinerList &L);

 LinerList.c中的内容

#include "LinerList.h"

//初始化线性表
void InitList(SLinerList &L) {
	L.length = 0;   //将线性表的长度置为空
}

//销毁线性表
void DestroyList(SLinerList &L)
{
	L.length = 0;  //将线性表的长度置为空,即就是销毁了线性表
}

test.c中的内容

#include"LinerList.h"

int main() {
	SLinerList SL1;  //定义一个线性表SL1
	
	InitList(SL1);    //将线性表SL1进行初始化操作
	SL1.length = 3;
	printf("线性表销毁前长度为%d\n", SL1.length);

	DestroyList(SL1); //将线性表SL1进行销毁操作
	printf("线性表销毁前长度为%d\n", SL1.length);

	return 0;
}

运行结果:
线性表销毁前长度为3
线性表销毁前长度为0

D:\C_WorkSpace\LinerList\x64\Debug\LinerList.exe (进程 20528)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

🍗线性表的顺序存储——求表长

Length(L);  //获取线性表的长度

 LinerList.h中的内容

//获取表长
int Length(SLinerList L);

 LinerList.c中的内容

//获取表长
int Length(SLinerList L) {
	return L.length;
}

test.c中的内容

#include"LinerList.h"

int main() {
	SLinerList SL1;  //定义一个线性表SL1
	
	InitList(SL1);    //将线性表SL1进行初始化操作
	SL1.length = 3;
	printf("线性表销毁前长度为%d\n", SL1.length);

	DestroyList(SL1); //将线性表SL1进行销毁操作
	printf("线性表销毁前长度为%d\n", SL1.length);

	int SL1_length = Length(SL1); //获取表长
	printf("线性表当前长度为%d\n", SL1.length);

	return 0;
}

运行结果:
线性表销毁前长度为3
线性表销毁前长度为0
线性表当前长度为0

D:\C_WorkSpace\LinerList\x64\Debug\LinerList.exe (进程 9764)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

🍗 线性表的顺序存储——判空

Empty(L);  //判断线性表是否为空

LinerList.h中的内容

//判断表是否为空
bool Empty(SLinerList L);

 LinerList.c中的内容

//判空
bool Empty(SLinerList L)
{
	if (L.length == 0) {
		return true;
	}
	else
	{
		return false;
	}
}

test.c中的内容

#include"LinerList.h"

int main() {
	SLinerList SL1;  //定义一个线性表SL1
	
	InitList(SL1);    //将线性表SL1进行初始化操作
	SL1.length = 3;
	printf("线性表销毁前长度为%d\n", SL1.length);

	DestroyList(SL1); //将线性表SL1进行销毁操作
	printf("线性表销毁前长度为%d\n", SL1.length);

	int SL1_length = Length(SL1); //获取表长
	printf("线性表当前长度为%d\n", SL1.length);

	if (Empty(SL1)) {    //判空
		printf("线性表为空\n");
	}
	else {
		printf("线性表不为空\n");
	}
	return 0;
}

运行结果:
线性表销毁前长度为3
线性表销毁前长度为0
线性表当前长度为0
线性表为空

D:\C_WorkSpace\LinerList\x64\Debug\LinerList.exe (进程 16848)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

🍗线性表的顺序存储——插入

ListInsert(&L,i,e):  //插入操作,在列表第i位置上插入

LinerList.h中的内容

//插入操作,在列表第i位置上插入元素e
bool ListInsert(SLinerList &L, int i, ElementType e);

 LinerList.c中的内容

//插入操作,在列表第i位置上插入元素e
bool ListInsert(SLinerList& L, int i, ElementType e)
{
	//判断插入位置的合法性
	if (i<1 || i>L.length + 1) {
		printf("插入位置不合法\n");
		return false;
	}
	//判断空间是否足够
	else if (L.length >= maxsize) {
		printf("线性表空间不够\n");
		return false;
	}
	else {
		//将i位置之后的元素全部后移一位
		for (int j = L.length; j > i - 1; j--) {
			L.data[j] = L.data[j - 1];
		}

		//空出i位置,插入元素
		L.data[i - 1] = e;

		//线性表长度++
		L.length++;
		return true;
	}
}

test.c中的内容

#include"LinerList.h"

int main() {
	SLinerList SL1;  //定义一个线性表SL1
	
	InitList(SL1);    //将线性表SL1进行初始化操作
	SL1.length = 3;
	printf("线性表销毁前长度为%d\n", SL1.length);

	DestroyList(SL1); //将线性表SL1进行销毁操作
	printf("线性表销毁前长度为%d\n", SL1.length);

	int SL1_length = Length(SL1); //获取表长
	printf("线性表当前长度为%d\n", SL1.length);

	if (Empty(SL1)==true) {    //判空
		printf("线性表为空\n");
	}
	else {
		printf("线性表不为空\n");
	}

	ElementType e = 2;
	if (ListInsert(SL1, 1, e) == true) {    //按位置插入元素
		printf("插入成功\n");
	}
	else {
		printf("插入失败\n");
	}
	return 0;
}

运行结果:

线性表销毁前长度为3
线性表销毁前长度为0
线性表当前长度为0
线性表为空
插入成功

D:\C_WorkSpace\LinerList\x64\Debug\LinerList.exe (进程 12568)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

 🍗线性表的顺序存储——删除

ListDelete(&L,i,&e):  //删除操作,在列表第i位置上删除

LinerList.h中的内容

//删除操作,在列表第i位置上删除
bool ListDelete(SLinerList& L, int i, ElementType &e);

 LinerList.c中的内容

//删除操作,在列表第i位置上删除
bool ListDelete(SLinerList& L, int i, ElementType &e)
{
	//判断删除位置是否合法
	if (i<1 || i>L.length) {
		printf("删除位置不合法\n");
		return false;
	}
	else {
		e = L.data[i - 1];  //返回被删除元素

		//将i位置处的后面元素都前移动
		for (int j = i - 1; j < L.length - 1; j++) {
			L.data[j] = L.data[j+1];
		}

		//线性表长度--
		L.length--;
		return true;
	}

}

test.c中的内容

#include"LinerList.h"

int main() {
	SLinerList SL1;  //定义一个线性表SL1
	
	InitList(SL1);    //将线性表SL1进行初始化操作
	SL1.length = 3;
	printf("线性表销毁前长度为%d\n", SL1.length);

	DestroyList(SL1); //将线性表SL1进行销毁操作
	printf("线性表销毁前长度为%d\n", SL1.length);

	int SL1_length = Length(SL1); //获取表长
	printf("线性表当前长度为%d\n", SL1.length);

	if (Empty(SL1)==true) {    //判空
		printf("线性表为空\n");
	}
	else {
		printf("线性表不为空\n");
	}

	ElementType e = 2;
	if (ListInsert(SL1, 1, e) == true) {    //按位置插入元素
		printf("插入成功,插入的元素为%d\n", e);
	}
	else {
		printf("插入失败\n");
	}

	ElementType delete_ele;
	if (ListDelete(SL1, 1, delete_ele)==true) {
		printf("删除成功,删除的元素为%d\n", delete_ele);
	}
	else {
		printf("删除失败!\n");
	}
	return 0;
}

运行结果:

线性表销毁前长度为3
线性表销毁前长度为0
线性表当前长度为0
线性表为空
插入成功,插入的元素为2
删除成功,删除的元素为2

D:\C_WorkSpace\LinerList\x64\Debug\LinerList.exe (进程 20704)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

 🍗线性表的顺序存储——按值查找

LocateElem(L,e);  //按值查找,获取元素e

LinerList.h中的内容

//按值查找,并返回其位序
int LocateElem(SLinerList L, ElementType e);

 LinerList.c中的内容

//按值查找,并返回其位序
int LocateElem(SLinerList L, ElementType e)
{
	for (int j = 0; j < L.length; j++) {
		if (L.data[j] == e) {
			return j + 1;  //返回位序
		}
	}
	return -1; //没找到
}

test.c中的内容

#include"LinerList.h"

int main() {
	SLinerList SL1;  //定义一个线性表SL1
	
	InitList(SL1);    //将线性表SL1进行初始化操作
	SL1.length = 3;
	printf("线性表销毁前长度为%d\n", SL1.length);

	DestroyList(SL1); //将线性表SL1进行销毁操作
	printf("线性表销毁前长度为%d\n", SL1.length);

	int SL1_length = Length(SL1); //获取表长
	printf("线性表当前长度为%d\n", SL1.length);

	if (Empty(SL1)==true) {    //判空
		printf("线性表为空\n");
	}
	else {
		printf("线性表不为空\n");
	}

	ElementType e = 2;
	if (ListInsert(SL1, 1, e) == true) {    //按位置插入元素
		printf("插入成功,插入的元素为%d\n", e);
	}
	else {
		printf("插入失败\n");
	}

	ElementType delete_ele;
	if (ListDelete(SL1, 1, delete_ele)==true) {
		printf("删除成功,删除的元素为%d\n", delete_ele);
	}
	else {
		printf("删除失败!\n");
	}

	//先插入三个数据
	ListInsert(SL1, 1, 3);  //插3
	ListInsert(SL1, 1, 2);  //插2
	ListInsert(SL1, 1, 7);  //插7
	ElementType v = 7;
	int location = LocateElem(SL1, v); //查找7
	if (location != -1) {
		printf("找到了,%d在线性表的第%d位上\n", v,location);
	}
	else {
		printf("线性表中无%d元素\n",v);
	}

	return 0;
}

运行结果:

线性表销毁前长度为3
线性表销毁前长度为0
线性表当前长度为0
线性表为空
插入成功,插入的元素为2
删除成功,删除的元素为2
找到了,7在线性表的第1位上

D:\C_WorkSpace\LinerList\x64\Debug\LinerList.exe (进程 19592)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

 🍗线性表的顺序存储——按位查找

GetElem(L,i);  //按位查找,获取第i个位置上的元素

LinerList.h中的内容

//按位查找,获取第i个位置上的元素的值
ElementType GetElem(SLinerList L, int i);

 LinerList.c中的内容

//按位查找,获取第i个位置上的元素的值
ElementType GetElem(SLinerList L, int i) {
	ElementType value = 0;
	if (i<1 || i>L.length) {
		printf("查找位置不合法\n");
		exit;
	}
	else {
		value = L.data[i - 1];
		return value;
	}
}

test.c中的内容

#include"LinerList.h"

int main() {
	SLinerList SL1;  //定义一个线性表SL1
	
	InitList(SL1);    //将线性表SL1进行初始化操作
	SL1.length = 3;
	printf("线性表销毁前长度为%d\n", SL1.length);

	DestroyList(SL1); //将线性表SL1进行销毁操作
	printf("线性表销毁前长度为%d\n", SL1.length);

	int SL1_length = Length(SL1); //获取表长
	printf("线性表当前长度为%d\n", SL1.length);

	if (Empty(SL1)==true) {    //判空
		printf("线性表为空\n");
	}
	else {
		printf("线性表不为空\n");
	}

	ElementType e = 2;
	if (ListInsert(SL1, 1, e) == true) {    //按位置插入元素
		printf("插入成功,插入的元素为%d\n", e);
	}
	else {
		printf("插入失败\n");
	}

	ElementType delete_ele;
	if (ListDelete(SL1, 1, delete_ele)==true) {
		printf("删除成功,删除的元素为%d\n", delete_ele);
	}
	else {
		printf("删除失败!\n");
	}

	//先插入三个数据
	ListInsert(SL1, 1, 3);  //插3
	ListInsert(SL1, 1, 2);  //插2
	ListInsert(SL1, 1, 7);  //插7
	ElementType v = 7;
	int location = LocateElem(SL1, v); //查找7
	if (location != -1) {
		printf("找到了,%d在线性表的第%d位上\n", v,location);
	}
	else {
		printf("线性表中无%d元素\n",v);
	}

	int loc = 1;
	printf("线性表中第%d的元素为%d\n",loc, GetElem(SL1, loc));//得到位序上的值
	return 0;
}

运行结果:

线性表销毁前长度为3
线性表销毁前长度为0
线性表当前长度为0
线性表为空
插入成功,插入的元素为2
删除成功,删除的元素为2
找到了,7在线性表的第1位上
线性表中第1的元素为7

D:\C_WorkSpace\LinerList\x64\Debug\LinerList.exe (进程 1372)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

 🍗线性表的顺序存储——打印列表

PrintList(L);  //打印列表

LinerList.h中的内容

//打印列表
void PrintList(SLinerList L);  

 LinerList.c中的内容

//打印列表
void PrintList(SLinerList L) {
	if (L.length == 0) {
		printf("链表为空!");
	}
	else {
		for (int j = 0; j < L.length; j++) {
			printf("%d-->", L.data[j]);
		}
		printf("\n");
	}
	
}

test.c中的内容

#include"LinerList.h"

int main() {
	SLinerList SL1;  //定义一个线性表SL1
	
	InitList(SL1);    //将线性表SL1进行初始化操作
	SL1.length = 3;
	printf("线性表销毁前长度为%d\n", SL1.length);

	DestroyList(SL1); //将线性表SL1进行销毁操作
	printf("线性表销毁前长度为%d\n", SL1.length);

	int SL1_length = Length(SL1); //获取表长
	printf("线性表当前长度为%d\n", SL1.length);

	if (Empty(SL1)==true) {    //判空
		printf("线性表为空\n");
	}
	else {
		printf("线性表不为空\n");
	}

	ElementType e = 2;
	if (ListInsert(SL1, 1, e) == true) {    //按位置插入元素
		printf("插入成功,插入的元素为%d\n", e);
	}
	else {
		printf("插入失败\n");
	}

	ElementType delete_ele;
	if (ListDelete(SL1, 1, delete_ele)==true) {
		printf("删除成功,删除的元素为%d\n", delete_ele);
	}
	else {
		printf("删除失败!\n");
	}

	//先插入三个数据
	ListInsert(SL1, 1, 3);  //插3
	PrintList(SL1);
	ListInsert(SL1, 1, 2);  //插2
	PrintList(SL1);
	ListInsert(SL1, 1, 7);  //插7
	PrintList(SL1);
	ElementType v = 7;
	int location = LocateElem(SL1, v); //查找7
	if (location != -1) {
		printf("找到了,%d在线性表的第%d位上\n", v,location);
	}
	else {
		printf("线性表中无%d元素\n",v);
	}

	int loc = 1;
	printf("线性表中第%d的元素为%d\n",loc, GetElem(SL1, loc));//得到位序上的值

	PrintList(SL1);
	return 0;
}

运行结果:

线性表销毁前长度为3
线性表销毁前长度为0
线性表当前长度为0
线性表为空
插入成功,插入的元素为2
删除成功,删除的元素为2
3-->
2-->3-->
7-->2-->3-->
找到了,7在线性表的第1位上
线性表中第1的元素为7
7-->2-->3-->

D:\C_WorkSpace\LinerList\x64\Debug\LinerList.exe (进程 8276)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值