数据结构学习笔记——顺序表的基本操作(超详细最终版+++)建议反复看看ヾ(≧▽≦*)o

Posted 晚风(●•σ )

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构学习笔记——顺序表的基本操作(超详细最终版+++)建议反复看看ヾ(≧▽≦*)o相关的知识,希望对你有一定的参考价值。

目录

前言

以下所有代码都经过测试,编译运行软件:Dev-C++ 5.11,若有表述和代码错误感谢指出!!!


一、顺序表的相关知识点

(一)顺序存储和链式存储
通过顺序存储的线性表称为顺序表,它是将线性表中所有元素按照其逻辑顺序,依次存储到指定存储位置开始的一块连续的存储空间里;而通过链式存储的链表中,每个结点不仅包含该元素的信息,还包含元素之间的逻辑关系的信息。

  • 顺序表实现简单,可以随机存取,其存储密度大,但是执行插入、删除操作需要移动大量元素,效率低,另外其存储空间需事先分配,容易造成空间浪费或溢出。
  • 链表不支持随机存取,只能顺序存取,通过指针来体现元素之间的逻辑关系,存储密度比顺序表小,其执行插入、删除操作不需要移动元素,只需修改指针,效率高,另外它还支持动态分配存储空间,不会造成空间浪费或溢出。

(二)顺序表的插入操作
1、最好情况
若在顺序表的表尾插入元素,则不需要执行元素后移操作,即最好情况,所以最好时间复杂度为O(1)
2、最坏情况
若在顺序表的表头插入元素,需要执行n次元素后移操作,即最坏情况,所以最坏时间复杂度为O(n)
3、平均情况
设在顺序表第i个位置插入元素的概率为pi=1/(n+1),即在长度为n的线性表中插入一个结点,所需移动元素的平均次数为:
1 n + 1 ∑ i = 1 n + 1 ( n − i + 1 ) = 1 n + 1 n ( n + 1 ) 2 = n 2 \\frac1n+1 \\sum_i=1^n+1 (n-i+1)=\\frac1n+1\\fracn(n+1)2=\\fracn2 n+11i=1n+1(ni+1)=n+112n(n+1)=2n
平均情况下,所需移动元素的平均次数为n/2,故顺序表插入操作的平均时间复杂度为O(n)
(三)顺序表的删除操作
1、最好情况
若删除顺序表的表尾元素,则不需要执行元素后移操作,即最好情况,所以最好时间复杂度为O(1),与顺序表的插入操作的最好情况一样。
2、最坏情况
若删除顺序表的表头元素,则执行n次移动操作,即最坏情况,所以最坏时间复杂度为O(n),与顺序表的插入操作的最坏情况一样。
3、平均情况
设删除顺序表第i个位置上元素的概率为pi=1/n,即在长度为n的线性表中删除一个结点,若删除第一个结点需移动n-1次,……,删除第n个结点移动0次:
1 n ∑ i = 1 n ( n − i ) = 1 n n ( n − 1 ) 2 = n − 1 2 \\frac1n \\sum_i=1^n (n-i)=\\frac1n\\fracn(n-1)2=\\fracn-12 n1i=1n(ni)=n12n(n1)=2n1
平均情况下,所需移动元素的平均次数为(n-1)/2,故顺序表的删除操作的平均时间复杂度为O(n)

二、顺序表的定义

以下操作均为顺序表的静态分配,所以其大小和空间是固定的,可通过MaxSize设置顺序表的最大长度。

#include<stdio.h>
#define MaxSize 10	//可自行更改最大长度
typedef struct 
	int data[MaxSize];	//元素
	int length;			//顺序表的当前长度
 SqList;		//顺序表的类型定义

三、顺序表的初始化

设置顺序表的初始长度为0,即L.length=0。

/*初始化顺序表*/
void InitList(SqList L) 
	L.length=0;

四、顺序表的建立

/*顺序表的建立*/
void CreatList(SqList &L) 
	printf("请输入建立顺序表的元素个数:\\n");
	scanf("%d",&L.length);
	for(int i=0; i<L.length; i++) 
		int number=i+1;
		printf("请输入第%d个整数:\\n",number);
		scanf("%d",&L.data[i]);
	

五、顺序表的输出

顺序表的输出,依次遍历从头到尾输出顺序表中各元素的值,即通过一个for循环,条件<L.length(顺序表的总长度),每次输出元素。

/*顺序表的输出(从头到尾输出顺序表中各元素的值)*/
void DispList(SqList L) 
	for(int i=0; i<L.length; i++)
		printf("%d ",L.data[i]);

结合以上功能函数,如下,创建一个顺序表,长度为6,其功能是创建一个顺序表并输入元素,再通过函数调用依次输出各元素,数据元素依次为2,6,0,-1,4,8,如下完整代码:

#include<stdio.h>
#define MaxSize 10
typedef struct 
	int data[MaxSize];
	int length;
 SqList;

/*1、初始化顺序表*/
void InitList(SqList L) 
	L.length=0;


/*2、顺序表的建立*/
void CreatList(SqList &L) 
	printf("请输入建立顺序表的元素个数:\\n");
	scanf("%d",&L.length);
	for(int i=0; i<L.length; i++) 
		int number=i+1;
		printf("请输入第%d个整数:\\n",number);
		scanf("%d",&L.data[i]);
	


/*3、顺序表的输出(从头到尾输出顺序表中各元素的值)*/
void DispList(SqList L) 
	for(int i=0; i<L.length; i++)
		printf("%d ",L.data[i]);


//主函数
int main() 
	SqList L;
	InitList(L);
	CreatList(L);
	printf("顺序表为:\\n"); 
	DispList(L);

首先输入要创建顺序表中的元素个数,然后依次输入各数据元素,最后输出该顺序表,运行结果如下:

六、顺序表的逆序输出

顺序表的逆序输出也就是交换通过折半法,交换数据元素,然后也是通过调用DispList()函数依次遍历顺序表输出。

/*将顺序表中的所有元素逆置并输出*/
void ReverseList(SqList L) 
	int temp;
	for(int i=0; i<L.length/2; i++) 
		temp=L.data[i];
		L.data[i]=L.data[L.length-i-1];
		L.data[L.length-i-1]=temp;
	
	DispList(L);	//调用输出函数

例如,接上一个例子,不过这次是逆序输出顺序表,如下完整代码:

#include<stdio.h>
#define MaxSize 10
typedef struct 
	int data[MaxSize];
	int length;
 SqList;

/*1、初始化顺序表*/
void InitList(SqList L) 
	L.length=0;


/*2、顺序表的建立*/
void CreatList(SqList &L) 
	printf("请输入建立顺序表的元素个数:\\n");
	scanf("%d",&L.length);
	for(int i=0; i<L.length; i++) 
		int number=i+1;
		printf("请输入第%d个整数:\\n",number);
		scanf("%d",&L.data[i]);
	


/*3、顺序表的输出(从头到尾输出顺序表中各元素的值)*/
void DispList(SqList L) 
	for(int i=0; i<L.length; i++)
		printf("%d ",L.data[i]);


/*4、将顺序表中的所有元素逆置并输出*/
void ReverseList(SqList L) 
	int temp;
	for(int i=0; i<L.length/2; i++) 
		temp=L.data[i];
		L.data[i]=L.data[L.length-i-1];
		L.data[L.length-i-1]=temp;
	
	DispList(L);


//主函数
int main() 
	SqList L;
	InitList(L);
	CreatList(L);
	printf("逆序输出顺序表:\\n");
	ReverseList(L);

运行结果如下:

七、顺序表的插入操作

顺序表的插入操作以位序进行插入元素,这里要注意位序是从1开始的,而c语言中的数组下标是从0开始的,这一点在插入操作中要明白,这里加了一个if语句判断输入的插入位置是否合法,若不合法则会返回false,插入后,要将其后的元素后移,最后数组长度加1。

/*顺序表的插入操作 (在L的位序i处插入元素e)*/
bool ListInsert(SqList &L,int i, int e) 
	if (i<1||i>L.length||L.length>=MaxSize)		//在[1,length+1]内有效且未存满或等于最大长度
		return false;		//插入失败返回 false
	for(int j=L.length; j>=i; j--)	//j变量等于顺序表的长度
		L.data[j]=L.data[j-1];	//将要插入的位置,第i个元素及以后的元素后移,先移动后面的元素,即数组下标小的赋给下标大的
	L.data[i-1]=e;			//由于数组的下标是从0开始的,所以位序要减一,即将要插入的元素e赋值给L.data[i-1]
	L.length++;		//数组长度加1
	return true;		//插入成功返回 true

例如,向之前所创建好的顺序表的位序为3(数组下标为2)处插入数据元素“7”,如下完整代码:

#include<stdio.h>
#define MaxSize 10
typedef struct 
	int data[MaxSize];
	int length;
 SqList;

/*1、初始化顺序表*/
void InitList(SqList L) 
	L.length=0;


/*2、顺序表的建立*/
void CreatList(SqList &L) 
	printf("请输入建立顺序表的元素个数:\\n");
	scanf("%d",&L.length);
	for(int i=0; i<L.length; i++) 
		int number=i+1;
		printf("请输入第%d个整数:\\n",number);
		scanf("%d",&L.data[i]);
	


/*3、顺序表的输出(从头到尾输出顺序表中各元素的值)*/
void DispList(SqList L) 
	for(int i=0; i<L.length; i++)
		printf("%d ",L.data[i]);


/*4、顺序表的插入操作 (在L的位序i处插入元素e)*/
bool ListInsert(SqList &L,int i, int e) 
	if (i<1||i>L.length||L.length>=MaxSize)		//在[1,length+1]内有效且未存满或等于最大长度
		return false;		//插入失败返回 false
	for(int j=L.length; j>=i; j--)	//j变量等于顺序表的长度
		L.data[j]=L.data[j-1];	//将要插入的位置,第i个元素及以后的元素后移,先移动后面的元素,即数组下标小的赋给下标大的
	L.data[i-1]=e;			//由于数组的下标是从0开始的,所以位序要减一,即将要插入的元素e赋值给L.data[i-1]
	L.length++;		//数组长度加1
	return true;		//插入成功返回 true


//主函数
int main() 
	SqList L;
	InitList(L);
	CreatList(L);
	printf("当前顺序表为:\\n");
	DispList(L);
	ListInsert(L,3,7);	//在顺序表L的位序为3处插入数据元素7
	printf("\\n");
	printf("插入后的顺序表为:\\n");
	DispList(L);

运行结果如下:

八、顺序表的删除操作

顺序表的删除操作同插入操作一样,也是通过位序插入/删除,删除目标元素后,其后的元素要向前移动一格,最后数组长度要减1。

/*顺序表的删除操作 (删除L中第i个位置的元素并引用变量e返回)*/
bool ListDelete(SqList &L,int i,int &e) 
	if (i<1||i>L.length)	//在[1,length+1]内有效
		return false; //删除失败返回true
	e=L.data[i-1];	//将要删除的元素赋值给e,由于是数组所以要i-1
	for(int j=i; j<L.length; j++)
		L.data[j-1]=L.data[j];	//将要删除的位置,第i个元素后的元素前移,先移动前面的元素,即下标大的赋值给下标小的
	L.length--;		//数组长度减1
	return true; 	//删除成功返回true

例如对创建的顺序表,删除第4个元素(位序为4),然后输出顺序表,完整代码如下:

#include<stdio.h>
#define MaxSize 10
typedef struct 
	int data[MaxSize];
	int length;
 SqList;

/*1、初始化顺序表*/
void InitList(SqList L) 
	L.length=0;


/*2、顺序表的建立*/
void CreatList(SqList &L) 
	printf("请输入建立顺序表的元素个数:\\n");
	scanf("%d",&L.length);
	for(int i=0; i<L.length; i++) 
		int number=i+1;
		printf("请输入第%d个整数:\\n",number);
		scanf("%d",&L.data数据结构与算法全套数据结构笔记持续更新

数据结构与算法全套数据结构笔记持续更新

数据结构--顺序表的c语言实现(超详细注释/实验报告)

数据结构学习笔记(数据结构概念顺序表的增删查改等)详细整理

数据结构与算法线性表的链式表示和实现,超详细C语言版

数据结构--单链表的c语言实现(超详细注释/实验报告)