线性表--顺序表-1

文章目录

  • 主要内容
  • 一.基础练习题
      • 1.从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。空出位置由最后元素填补,若顺序表为空,则显示出错信息并退出运行。
          • 代码如下(示例):
      • 2.设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)。
          • 代码如下(示例):
      • 3.将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表。
          • 代码如下(示例):
      • 4.已知在一维数组A[m+n]中依次存放两个线性表(a1,a2,....,am)和(b1,b2,...bn).编写一个函数,将数组中两个顺序表的位置互换,即将(b1,b2,...bn)放在(a1,a2,...am)的前面。
          • 代码如下(示例):
      • 5.设将n(n>1)个整数存放到一维数组R中。设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(O
          • 代码如下(示例):
  • 总结

主要内容

  1. 顺序表基础练习题

一.基础练习题

1.从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。空出位置由最后元素填补,若顺序表为空,则显示出错信息并退出运行。

代码如下(示例):
算法思想:搜索整个顺序表,查找最小元素并记住其位置,搜索结束后用最后一个元素填补空出的原最小值元素的位置。

bool Del_Min(sqList &L,ElemType &value){
//删除顺序表L中最小元素结点,并通过引用型参数value返回其值
//若删除成功,则返回true;否则返回false
	if(L.length==0)
		return false; //表空,中止操作返回
	value=L.data[0];
	int pos=0; //假定0号元素的值最小
	for(int i=1;i<L.length;i++) //循环,寻找具有最小值的元素
		if(L.data[i]<value){ //让value记忆当前具有最小值的元素
		value=L.data[i];
		pose=i;
		}
	L.data[pos]=L.data[L.length-1]; //空出的位置由最后一个元素提填补
	L.length--;
	return true; //此时,value即为最小值
}

2.设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)。

代码如下(示例):
算法思想:扫描顺序表L的前半部分元素,对于元素L.data[i](0<=i<L.length/2),
将其与后半部分的对应元素L.data[L.length-i-1]进行交换。
 
void Reverse(Sqlist &L){
	Elemtype temp; //辅助变量
	for(i=0;i<L.length/2;i++){
	temp=L.data[i]; //交换L.data[i]与L.data[L.length-i-1]
	L.data[i]=L.data[L.length-i-1];
	L.data[L.length-i-1]=temp;
	}
}

3.将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表。

代码如下(示例):
算法思想:首先,按顺序不断取下两个顺序表表头较小的节点存入新的顺序表中。
然后,看哪个表还有剩余,将剩下的部分加到新的顺序表后面。

bool Merge(SeqList A,SeqList B,SeqList &C){
//将有序顺序表A和B合并为一个新的有序顺序表C
	if(A.length+B.length>C.maxSize) //大于顺序表的最大长度
		return false;
	int i=0,j=0,k=0;
	while(i<A.length&&j.B.length){
		if(A.data[i]<=B.data[j])
			C.data[k++]=A.data[i++];
		else
			C.data[k++]=B.data[j++];
	}
	while(i<A.length) //还剩一个没有比较完的顺序表
		C.data[k++]=A.data[i++];
	while(j<B.length)
		C.data[k++]=B.data[j++];
	C.length=k;
	return true;
}

4.已知在一维数组A[m+n]中依次存放两个线性表(a1,a2,…,am)和(b1,b2,…bn).编写一个函数,将数组中两个顺序表的位置互换,即将(b1,b2,…bn)放在(a1,a2,…am)的前面。

代码如下(示例):
算法思想:先将数组A[m+n]中的全部元素(a1,a2,...am,b1,b2,...bn)原地逆置为(bn,bn-1,...b1,am,am-1,..a1),
再对前n个元素和后m个元素分别使用逆置算法,即可得到(b1,b2,..bn,a1,a2,...am),从而实现顺序表的位置互换。

 typedef int DataType;
 void Reverse(DataType A[],int left,int right,int arraySize){
 	if(left>=right || right>=arraySize)
 		return;
 	int mid=(left+right)/2;
	for(i=0;i<mid-left;i++){
		DataType temp=A[left+i];
		A[left+i]=A[right-i];
		A[right-i]=temp;
	}
}
void Exchange(DataType A[],int m,int n,int araySize){
	Reverse(A,0,m+n-1,arraySize);
	Reverse(A,0,n-1,arraySize);
	Reverse(A,n,m+n-1,arraySize);
}

5.设将n(n>1)个整数存放到一维数组R中。设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(O

要求:1) 给出算法的基本设计思想。
2)根据设计思想,采用 C或 C++或 Java 语言描述算法,关键之处给出注释
3) 说明你所设计算法的时间复杂度和空间复杂度

代码如下(示例):
算法思想:可将这个问题视为把数组 ab 转换成数组 ba(a代表数组的前p 个元素,b代表数组中余下的n-p个元素),
先将a逆置得到a^(-1)b,再将b逆置得到a^(-1)b^(-1),最后将整个a逆置得到(a^(-1)b^(-1)^-1))= ba。
设 Reverse 函数执行将数组元素逆置的操作,对abcdefgh 向左循环移动3(p=3)个位置的过程如下:
Reverse(0,p-1)得到 cbadefgh:
Reverse(pn-1)得到 cbahgfed;
Reverse(0,n-1)得到defghabc;:Reverse 中,两个参数分别表示数组中待转换元素的始末位置。
void Reverse(int R[],int from,int to){
	int i,temp;
	for(i=0;i<(to-from+1)/2;i++)
	{temp=R[from+i];R[from+i]=R[to-i];R[to-i]=temp;}
} //Reverse
void Converse(int R[],int n,int p){
	Reverse(R,0,p-1);
	Reverse(R,p,n-1);
	Reverse(R,0,n-1);
}
上述算法中三个Reverse函数的时间复杂度分别为 O(p/2)O((n-p)/2)0(n/2),
故所设计的算法的时间复杂度为 O(n),空间复杂度为 O(1)。
另解,借助辅助数组来实现。
算法思想:创建大小为p的辅助数组 S,将R中前p 个整数依次暂存在 S中,同时将 R中后 n-p 个整数左移,
然后将 S中暂存的p个数依次放回到R中的后续单元。时间复杂度为 O(n),空间复杂度为 O(p)

总结

以上是今天要讲的内容,练习了一些线性表–顺序表的习题。

你可能感兴趣的:(算法与数据结构,算法,数据结构,c语言,运维)