顺序表的常用算法

时间:2022-10-29 11:17:15
//问题一:删除最小元素,并用最后一个元素填补
bool delMin(SqList &L,elemType &val){
	if(L.length==0){
		printf("顺序表为空!\n");
		return ERROR;
	}
	elemType min = L.elems[0];
	int index = 0;
	for(int i=1;i<L.length;i++){
		if(L.elems[i]<min){
			min=L.elems[i];
			index=i;
		}
	}
	val=L.elems[index];
	L.elems[index]=L.elems[--L.length];
	return OK;
}

  

//问题二:逆置元素
void reverse(SqList &L){
	int i=0,j=L.length-1;
	int t;
	while(i<j){
		t=L.elems[i];
		L.elems[i]=L.elems[j];
		L.elems[j]=t;
		i++;
		j--;
	}
}

 

//问题三:删除所有值为x的数据元素
void delX(SqList &L,elemType x){
	int k=0;
	for(int i=0;i<L.length;i++){
		if(L.elems[i]!=x){
			L.elems[k++]=L.elems[i];
		}
	}
}
//方法二
void delX2(SqList &L,elemType x){
	int l=0,r=L.length-1;
	while(l<r){
		while(l<r&&L.elems[l]!=x)
			l++;
		while(r>l&&L.elems[r]==x){
			r--;
			L.length--;
		}
		if(l<r){
			L.elems[l]=L.elems[r];
			r--;
			L.length--;
		}
	}
}

  

//问题四:从有序顺序表中删除值在t-s之间的所有元素
bool delBetween(SqList &L,int t,int s){
	if(L.length==0||t>s)
		return ERROR;	//错误
	int i=0;
	int d;		//元素的值
	int st=-1;	//在范围内的开始元素的索引值
	int k=0;	//在范围内的元素的个数
	for(i;i<L.length;i++){
		d=L.elems[i];
		if(d>=t&&d<=s){
			if(st==-1)
				st=i;
			k++;
		}
		if(d>s)break;	//因为是有序的,后面都不在范围内
	}
	if(k){	//如果有在范围内的
		for(int j=st+k;j<L.length;j++){	//向前移K个位置
			L.elems[j-k]=L.elems[j];
		}
		L.length-=k;	
	}
	return OK;
}

  

//问题五:从顺序表(无序)中删除值在t-s之间的所有元素
bool delBetween2(SqList &L,int t,int s){
	if(L.length==0||t>s)
		return ERROR;	//错误
	int k=0;
	int v;
	for(int i=0;i<L.length;i++){
		v=L.elems[i];
		if(v<t||v>s){
			L.elems[k]=v;
			k++;
		}
	}
	L.length=k;
	return OK;
}

  

//问题六:从有序顺序表中删除值重复的元素
void delRepeat(SqList &L){
	int k=0;
	int len = L.length;
	for(int i=1;i<len;i++){
		if(L.elems[k]!=L.elems[i]){
			L.elems[++k]=L.elems[i];
		}
	}
	L.length = k+1;
}

  

/*问题七:  数组中存放着两个顺序表 (a1a2a3...am b1b2b3...bn),
			交换他们的位置变为(b1b2b3...bn a1a2a3...am)
*/
void reverse(SqList &L,int st,int end){	//翻转位置st到end的元素
	int t;
	while(st<end){
		t=L.elems[st];
		L.elems[st]=L.elems[end];
		L.elems[end]=t;
		st++;
		end--;
	}
}
void exchange(SqList &L,SqList &A,SqList &B){
	int la=A.length;
	int lb=B.length;
	reverse(L,0,la-1);
	reverse(L,la,la+lb-1);
	reverse(L,0,la+lb-1);
}

  

//问题九:有序顺序表,查找值为X的元素,若找到将他与后继元素交换,未找到则将其插入并仍然有序
void findX(SqList &L,int x){
	int index = 0;
	int i=0;
	for(i;i<L.length;i++){
		if(L.elems[i]==x){		//找到了x
			if(i!=L.length-1){	//不是最后一个则有后继元素
				int t=L.elems[i];
				L.elems[i]=L.elems[i+1];
				L.elems[i+1]=t;
				return;
			}
		}else if(L.elems[i]>x){
			index=i;		//未找到,index为插入位置
			break;
		}
	}
	for(i=L.length;i>index;i--){
		L.elems[i]=L.elems[i-1];
	}
	L.elems[index]=x;
	L.length++;
}

  

//问题十:将一维数组A中的元素循环左移p个位置
void reverse(int a[],int st,int end){	//翻转位置st到end的元素
	int t;
	while(st<end){
		t=a[st];
		a[st]=a[end];
		a[end]=t;
		st++;
		end--;
	}
}
void moveP(int A[],int len,int p){
	//思路与问题七类似,现将前p个翻转,并把剩余的翻转,最后全部翻转
	reverse(A,0,p-1);
	reverse(A,p,len-1);
	reverse(A,0,len-1);
}

  

//问题十一:求两个上升序列合并后的中位数
float searchMid(int a[],int b[],int n){
	int l1=0,m1,r1=n-1,l2=0,m2,r2=n-1;	//分别表示数组a、b的开始、中间、结束位置
	while(l1!=r1||l2!=r2){
		m1=(l1+r1)/2;
		m2=(l2+r2)/2;
		if(a[m1]==b[m2])
			return a[m1]*1.0;
		else if(a[m1]<b[m2]){
			if((l1+r1)%2==0){//奇数个
				l1=m1;		//舍弃a中间点以前的并保留中间点
				r2=m2;		//舍弃b中间点之后的并保留中间点
			}else{
				l1=m1+1;	//舍弃a中间点之前的包括中间点		
				r2=m2;		//舍弃b中间点之前的包括中间点
			}
		}else{
			if((l1+r1)%2==0){//奇数个
				r1=m1;		//舍弃a中间点以后的并保留中间点
				l2=m2;		//舍弃b中间点之前的并保留中间点
			}else{
				r1=m1;		//舍弃a中间点之后的包括中间点		
				l2=m2+1;	//舍弃b中间点之前的包括中间点
		}
			
	}
}
	return (a[l1]+b[l2])/2.0;
	
}

  

//问题十二:查找数组中是否有出现次数超过一半的元素,有则返回
bool check(int a[],int len,int c){
	int cnt=0;
	for(int i=0;i<len;i++){
		if(a[i]==c)
			cnt++;
	}
	return cnt>len/2;
}

int majority(int a[],int len){
	int c=a[0];
	int cnt=1;
	for(int i=0;i<len;i++){
		if(a[i]==c)
			cnt++;
		else{
			if(cnt>0)
				cnt--;
			else{
				c=a[i];
				cnt=1;
			}
		}
	}
	if(cnt)
		return check(a,len,c)?c:0;
	else
		return 0;

}

//方法二:快速排序的思路
int majority2(int a[],int len){
	int temp=a[0];
	int i=0;
	int j=len-1;
	while(i<j)
    {
        while(i<j && a[j]>=temp)
            j--;
            if(i<j)
                a[i]=a[j];
        while(i<j && a[i]<=temp)
            i++;
            if(i<j)
                a[j]=a[i];
    }
    a[i]=temp;
	return check(a,len,a[len/2])?a[len/2]:0;


}