线性表中的元素循环左移p个位置问题

一 概述

对于顺序表L循环左移p(0<p<L1.length)个位置,即将L中的数据由(X0,X1,...,Xn-1)变换为(Xp,Xp+1,...,Xn-1,x0,x1,...,xp-1)。

二 算法设计思想

该问题可以视为将序列L的(AB)部分转换为序列L的(BA)部分,其中A代表顺序表前p个元素部分,B代表数组中余下的L.length-p个元素部分,先将A部分的元素逆置得到((-B)A),然后将B部分的元素逆置((-A)(-B)),最后将整个表进行逆置得到(BA)。

算法的设计步骤:

  • 设计一个逆置函数reverse(SqList L,low,high),初始化一个逆置序列L:1 2 3 4 5 6;
  • 对序列L实现循环左移3个位置即(p = 3);
  • 实现A部分的逆置即reverse(SqList L,0,2);
  • 实现B部分的逆置即reverse(SqList L,3,L.length-1);
  • 实现((-A)(-B))逆置得到BA即Reverse(SqList L,o,L.length-1);

注意,顺序表内部实现是数组,数组的下标是从0开始至L.length-1结束,而顺序表数据位是从1开始至L.length结束。

三 算法是实现

#include<iostream>//输入头 
using namespace std;//标准输入输出

typedef int Status;
typedef int ElemType;

#define MAXSIZE 100
#define ERROR -1
#define OK 0

typedef struct {
	ElemType *elem;
	int length;
}SqList; 

Status init_Queue(SqList &L){
	
	L.elem = new ElemType[MAXSIZE]; //初始化最大长度的顺序表 
	
	if(!L.elem){
		return ERROR; //初始化失败 
	}
	
	L.length = 0; //初始时数据表为空 
	return OK;
}

SqList reverse(SqList &L,int low,int high) {
	
	ElemType temp;
	
	for(int i = 0; i < (high-low+1)/2; i++) {
		
		temp = L.elem[low+i];
		L.elem[low+i] = L.elem[high-i];
		L.elem[high-i] = temp; 
	}
	return L;
}

int main(){
	SqList L;
	 
	cout<<"1.初始化顺序表!\n";
	cout<<"2.输入6个不同的数字!\n";
	cout<<"3.循环左移3个位置后的序列!\n";
	cout<<"0.退出!"<<endl<<endl;
	
	int elect = -1;
	
	while(elect !=0){
		cout<<"请选择你的后续操作:"; 
		cin>>elect;
		switch(elect){
			case 1:
				if(!init_Queue(L)){
					cout<<"初始化顺序表成功!"<<endl; 
				}else{
					cout<<"初始化顺序表失败!"<<endl; 
				}
				break;
			case 2:
				cout<<"请输入6不同数字:" ;
				for(int i = 0; i < 6; i++){
					cin>>L.elem[i];
					L.length = 6; 
				}
				break;
			case 3:
				L = reverse(L,0,2);
				cout<<"逆置0~p-1位置的数据序列为:" ;
				for(int i = 0; i <L.length; i++ ){
				 cout<<L.elem[i]<<" ";
				} 
				cout<<endl;
				L = reverse(L,3,L.length-1);
				cout<<"逆置p~L.length位置的数据序列为:" ;
				for(int i = 0; i < L.length; i++ ){
				 cout<<L.elem[i]<<" ";
				} 
				cout<<endl;
				L = reverse(L,0,L.length-1);
				cout<<"循环左移3个位置后的数据序列为:" ;
				for(int i = 0; i < L.length; i++ ){
				 cout<<L.elem[i]<<" ";
				} 
				cout<<endl; 
				break;
		}
	}
	return 0;
}

算法结果:

  

四 算法的时间复杂度与空间复杂度分析

时间复杂度:上述reverse(SqList L,int low,int high)方法的三次调用的时间复杂度分别为:

  • 实现A部分的逆置即reverse(SqList L,0,2),时间复杂度为O(p/2);
  • 实现B部分的逆置即reverse(SqList L,3,L.length-1),时间复杂度为O((L.length - p)/2);
  • 实现((-A)(-B))逆置得到BA即Reverse(SqList L,o,L.length-1),时间复杂度为O(L.length/2);

故,该算法的整体时间复杂度为O(n);

空间复杂度:根据原地工作空间复杂度,即算法所需的辅助空间为常量,即空间复杂度为O(1);

猜你喜欢

转载自blog.csdn.net/calm_encode/article/details/107012436