草庐IT

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

晚风(●•σ ) 2023-04-10 原文

目录

前言

以下所有代码都经过测试,编译运行软件: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 \frac{1}{n+1} \sum_{i=1}^{n+1} (n-i+1)=\frac{1}{n+1}\frac{n(n+1)}{2}=\frac{n}{2} 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 \frac{1}{n} \sum_{i=1}^{n} (n-i)=\frac{1}{n}\frac{n(n-1)}{2}=\frac{n-1}{2} 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[i]);
	}
}

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

/*4、顺序表的删除操作 (删除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
}

//主函数
int main() {
	SqList L;
	int a;
	int e=0;	//初始化e的值 
	InitList(L);
	CreatList(L);
	printf("当前顺序表为:\n");
	DispList(L);
	printf("\n");
	printf("请输入想删除的元素位置:\n",a);
	scanf("%d",&a);
	if (ListDelete(L,a,e))
		printf("已删除顺序表中第%d个元素,其元素值为%d\n",a,e);
	else
		printf("输入的位序i不合法,删除操作失败!\n");
	printf("当前顺序表为:\n");
	DispList(L);
	return 0;
}

运行结果如下:

九、顺序表的按位和按值查找

顺序表的按位查找是以数组下标进行查找的,所以位序要减1,即L.data[i-1]。

/*顺序表的按位查找 (获取L中第i个位置元素的值)*/
int GetElem(SqList L,int i) {
	return L.data[i-1];		//立即找到第i个元素
}

顺序表的按值查找是,查找L中第一个元素值等于e的元素,它会依次沿着顺序表向后查找,找到后返回其位序。

/*顺序表的按值查找 (查找L中第一个元素值等于e的元素并返回其次序)*/
int LocateElem(SqList L,int e) {
	for(int i=0; i<L.length; i++) 	//依次从前往后查找
		if(L.data[i]==e)
			return i+1;	//数组下标为i的元素值为e,返回其位序i+1(数组从0开始)
	return 0;	//未找到元素,退出循环查找失败
}

例如对创建的顺序表,查询顺序表中第3个位置的数据元素,另外查询顺序表中第一个元素值等于“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[i]);
	}
}

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

/*4、顺序表的按位查找 (获取L中第i个位置元素的值)*/
int GetElem(SqList L,int i) {
	return L.data[i-1];		//立即找到第i个元素
}

/*5、顺序表的按值查找 (查找L中第一个元素值等于e的元素并返回其次序)*/
int LocateElem(SqList L,int e) {
	for(int i=0; i<L.length; i++) 	//依次从前往后查找
		if(L.data[i]==e)
			return i+1;	//数组下标为i的元素值为e,返回其位序i+1(数组从0开始)
	return 0;	//未找到元素,退出循环查找失败
}

//主函数
int main() {
	SqList L;
	int a,b;
	InitList(L);
	CreatList(L);
	printf("顺序表为:\n");
	DispList(L);
	printf("\n");
	printf("按位查找第3个元素的值:\n");
	a=GetElem(L,3);
	printf("%d \n",a);
	printf("按值查找值为4的元素:\n");
	b=LocateElem(L,4);
	printf("%d \n",b);
}

运行结果如下:

基本操作的完整代码

以上顺序表基本操作的完整代码如下:

#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);	//调用输出函数
}

/*5、顺序表的插入操作 (在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
}

/*6、顺序表的删除操作 (删除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
}

/*7、顺序表的按位查找 (获取L中第i个位置元素的值)*/
int GetElem(SqList L,int i) {
	return L.data[i-1];		//立即找到第i个元素
}

/*8、顺序表的按值查找 (查找L中第一个元素值等于e的元素并返回其次序)*/
int LocateElem(SqList L,int e) {
	for(int i=0; i<L.length; i++) 	//依次从前往后查找
		if(L.data[i]==e)
			return i+1;	//数组下标为i的元素值为e,返回其位序i+1(数组从0开始)
	return 0;	//未找到元素,退出循环查找失败
}

十*、顺序表删除的常用操作

  1. 删除顺序表中的最小值
  2. 删除顺序表中的所有特定值的元素
  3. 删除顺序表值在特定区间的元素
  4. 删除顺序表中重复元素
  5. 删除有序表中重复元素

具体的实现步骤感兴趣的小伙伴可以看之前这篇文章:
数据结构学习笔记:顺序表的删除操作及其演化题目总结

十一*、顺序表的常用合并操作

  1. 顺序表的合并操作
    若要将两个顺序表的数据元素合并,通过创建一个CombineList1()函数,将顺序表L1和顺序表L2分别添加至顺序表L3中,该函数中包含三个参数,分别是SqList L1,SqList L2,SqList &L3(顺序表L3由于被更改,所以要用引用符号),如下:
bool CombineList1(SqList L1,SqList L2,SqList &L3) {
...
}

只需设置一个while()循环,条件是该顺序表的长度,每次将该顺序表的值赋给最终顺序表,且每次循环变量都加1,如下:

while(i<L1.length)
	L3.data[k++]=L1.data[i++];
while(j<L2.length)
	L3.data[k++]=L2.data[j++];

该算法的完整代码:

/*合并两个顺序表*/
bool CombineList1(SqList L1,SqList L2,SqList &L3) {
	InitList(L3);
	int i=0,j=0;
	int k = 0;
	while(i<L1.length)
		L3.data[k++]=L1.data[i++];
	while(j<L2.length)
		L3.data[k++]=L2.data[j++];
	L3.length=k;
	return true;
}

例如,创建两个顺序表L1、L2,顺序表L1的数据元素依次为4、5、0、2、-1;顺序表L2的数据元素依次为8、1、4、7、2,将这两个顺序表合并为顺序表L3,并最后输出顺序表L3:
代码如下:

#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、合并两个顺序表*/
bool CombineList1(SqList L1,SqList L2,SqList &L3) {
	InitList(L3);
	int i=0,j=0;
	int k = 0;
	while(i<L1.length)
		L3.data[k++]=L1.data[i++];
	while(j<L2.length)
		L3.data[k++]=L2.data[j++];
	L3.length=k;
	return true;
}

//主函数
int main() {
	SqList L1,L2,L3;
	int a,b;
	InitList(L1);
	InitList(L2);
	InitList(L3);
	printf("建立第一个顺序表!\n");
	CreatList(L1);
	DispList(L1);
	printf("\n");
	printf("建立第二个顺序表!\n");
	CreatList(L2);
	DispList(L2);
	printf("\n");
	printf("合并后的顺序表如下:\n");
	CombineList1(L1,L2,L3);
	DispList(L3);
}

运行结果如下:

  1. 有序顺序表的合并操作
    若要将两个有序顺序表的数据元素合并,我们则要对上述代码进行修改,即按顺序依次取两个顺序表较小的数据元素存入新的顺序表中,然后对剩余的数据元素再添加至新的顺序表的后面,创建一个函数CombineList2():
bool CombineList2(SqList L1,SqList L2,SqList &L3) {
...
}

该算法的完整代码如下:

/*5、合并有序顺序表*/
bool CombineList2(SqList L1,SqList L2,SqList &L3) {
	if(L1.length+L2.length>MaxSize)
		return false;
	int i=0,j=0;
	int k = 0;
	InitList(L3);
	while(i<L1.length&&j<L2.length) {	//对两个顺序表中的元素两两比较,将小者存入结果表 
		if(L1.data[i]<=L2.data[j])
			L3.data[k++]=L1.data[i++];
		else
			L3.data[k++]=L2.data[j++];
	}
	while(i<L1.length)
		L3.data[k++]=L1.data[i++];
	while(j<L2.length)
		L3.data[k++]=L2.data[j++];
	L3.length=k;
	return true;
}

注:该代码参考《王道 数据结构 考研复习指导》
例如,创建两个有序顺序表L1、L2,有序顺序表L1的数据元素依次为-5、0、3、7;有序顺序表L2的数据元素依次为1、7、10,将这两个有序顺序表合并为有序顺序表L3,并最后输出有序顺序表L3:
代码如下:

#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、合并有序顺序表*/
bool CombineList2(SqList L1,SqList L2,SqList &L3) {
	if(L1.length+L2.length>MaxSize)
		return false;
	int i=0,j=0;
	int k = 0;
	InitList(L3);
	while(i<L1.length&&j<L2.length) {	//对两个顺序表中的元素两两比较,将小者存入结果表 
		if(L1.data[i]<=L2.data[j])
			L3.data[k++]=L1.data[i++];
		else
			L3.data[k++]=L2.data[j++];
	}
	while(i<L1.length)
		L3.data[k++]=L1.data[i++];
	while(j<L2.length)
		L3.data[k++]=L2.data[j++];
	L3.length=k;
	return true;
}

//主函数
int main() {
	SqList L1,L2,L3;
	int a,b;
	InitList(L1);
	InitList(L2);
	InitList(L3);
	printf("建立第一个有序顺序表!\n");
	CreatList(L1);
	DispList(L1);
	printf("\n");
	printf("建立第二个有序顺序表!\n");
	CreatList(L2);
	DispList(L2);
	printf("\n");
	printf("合并后的有序顺序表如下:\n");
	CombineList2(L1,L2,L3);
	DispList(L3);
}

运行结果如下:

后续更新分割线……

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

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  4. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  5. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  6. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  7. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  8. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  9. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  10. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

随机推荐