数据结构——顺序表

线性表

线性表逻辑结构

线性表定义和基本操作

定义

线性表是具有相同数据类型的n(n>0)个数据元素的有限序列,其中n为表长,当n=0时线性表是一个空表。
线性表的特点:元素的个数有限,表中元素具有逻辑上的顺序性,表中元素有其先后次序,表中元素都是数据元素,每个元素都是单个元素,表中元素的数据类型相同,这意味着每个元素占有相同大小的储存空间。

基本操作

InitList(&L),初始化线性表。
Length(L):求表长。
LocateElem(L,e):按置查找,e为查找的值
GetELem(L,i):按位查找,i为第i个元素
ListInsert(&L,i,e):插入操作。将e插入第i位置
ListDelete(&L,i,&e):删除操作,删除第i位置的元素
PrintList(L):输出操作。输出所有元素的值
Empty(L):判空操作。
DestroyList(&L):销毁操作,销毁线性表。

线性表的顺序表示

顺序表定义

线性表的顺序储存又顺序表,是通过一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理上也相邻。
假设线性表的元素类型为ElemType,则线性表的顺序存储类型描述为

typedef struct{
	ElemType data[MaxSize]
	int length;
}SqList;

顺序表上基本操作的实现

插入
bool ListInsert(SqList &L,int i,ElemType e){
	if(i<1||i>L.length+)
		return false;
	if(L.length>=MaxSize)
		return false;
	for(int j=L.length;j>=1;j--)
		L.data[j]=L.data[j-i];
	L.data[i-1]=e;
	L.length++;
	return true;
} 
删除
bool ListDelete(SqList &L,int i,ElemType e){
	if(i<1||i>L.length+)
		return false;
	e=L.data[i-1];
	for(int j=i;=j<L.length;j++)
		L.data[j-1]=L.data[j];
	L.length--;
	return true;
} 
按置查找
int LocateElem(SqList L,ElemType e){
	int i;
	for(i=0;i<L.length;i++)
		if(L.data[i]==e)
			return i+1;
	return 0;
} 

算法应用

删除有序表中值大于x小于y的元素
bool delete_x_y_orderly(SqList &L,int x,int y){
	int a=-1;
	int b=-1;
	if(L.length==0){
			cout<<"此表为空"<<endl; 
			return false;
		}
		if(L.data[L.length-1]<x){
			cout<<"错误:x大于最大值"<<endl;
			return false;
		}
		if(L.data[0]>y){
			cout<<"错误:y小于最小值"<<endl;
			return false;
		}
		if(x>y){
			cout<<"错误:x大于y"<<endl;
			return false;
		}
	for(int i=0;i<L.length;i++){
		
		if(L.data[i]>x&&a==-1){
			a=i;
		}
		if(L.data[i]>y&&b==-1){
			b=i-1;
		}
		if(a!=-1&&b!=-1&&b>a){
			L.data[a+i-b-1]=L.data[i-1];
		}
	}
	L.length-=b-a-1;
	return true;
}
删除无序表中值大于x小于y的元素
bool delete_x_y_disorder(SqList &L,int x,int y){
	if(L.length==0){
		cout<<"错误:此表为空"<<endl; 
		return false;
	}
	if(x>y){
		cout<<"错误;x大于y"<<endl; 
		return false;
	}
	int a=0;
	for(int i=0;i<L.length;i++){
		if(L.data[i]<x||L.data[i]>y){
			L.data[a]=L.data[i];
			a++;
		}
	}
	L.length=a;
}
元素置逆
bool reverse(SqList &L){
	int temp;
	for(int i=0;i<L.length/2;i++){
		temp=L.data[i];
		L.data[i]=L.data[L.length-1-i];
		L.data[L.length-1-i]=temp;
	}
	return true;
}
删除重复元素
bool delete_repeat(SqList &L){
	int a=0;
	int b=0;
	for(int i=0;i<L.length;i++){
		for(int j=i-1;j>=0;j--){
			if(L.data[i]==L.data[j]){
				break;
			}
		}
		if(b==0){
			L.data[a]=L.data[i];
			a++;
		}
		b=0;
	}
	L.length=a;
	return true;
}
把两个有序表融合成一个有序表
bool marge(SqList A,SqList B,SqList &C){
	if(A.length+B.length>C.length){
		return false;
	}
	int i,j,k;
	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;
} 
在一个有序顺序表里面查找值为x的元素,并将其与其后继元素互换,若没有值为x的元素则添加进顺序表使其仍然有序
bool wangdao9_2(SqList &L,int x){
	int max=L.length-1;
	int min=0;
	int mid;
	int temp;
	while(max>min){
		mid=(max+min)/2;
		if(L.data[mid]==x){
			temp=L.data[mid];
			L.data[mid]=L.data[mid+1];
			L.data[mid+1]=temp;
			return true;
		}
		if(L.data[mid]>x){
			max=mid;
		} 
		else{
			min=mid;
		}
		
	}
	} 
使元素后移X位(三步反转法)
bool reverse(SqList &L,int from,int to){
	int temp,i;
	for(int i=0;i<(to-from)/2;i++){
		temp=L.data[from+i];
		L.data[from+i]=L.data[to-i];
		L.data[to-i]=temp;
	}
	return true;
}
bool backmovep(SqList &L){
	int x;
	reverse(L,0,x-1);
	reverse(L,x,L.length);
	reverse(L,0,L.length);
}
两个长度相同的升序序列,求两个序列合并之后的中位数,位置在序列长度二分之一处的数称为中位数(分别比较中位数法)
int M_search(int A[],int B[],int n){
	int from1=0,to1=n-1,m1,from2=0,to2=n-1,m2;
	while(to1!=from1||to2!=from2){
		m1=(to1+from1)/2;
		m2=(to2+from2)/2;
		if(A[m1]==B[m2])
			return A[m1];
		if(A[m1]<B[m2]){
			if((to1+from1)%2==0){
				from1=m1;
				to2=m2;
			}
			else{
				from1=m1+1;
				to2=m2;
			}
		}
		else{
			if((to1+from1)%2==0){
				from2=m2;
				to1=m1;
			}
			else{
				from2=m2+1;
				to1=m1;
			}
		}	
	}
	return A[from1]<B[from2]?A[from1]:B[from2];
} 
找出一个数量超过序列长度二分之一的元素并输出该元素若无此元素返回-1(重复数计数法,遇到同样的加一不同的减一,为零则换元素,最后得到的数遍历查看是否大于一半)
int Majority(int A[],int n)
{
	int i,c,count=1;
	c=A[0];
	for(i=1;i<n;i++){
		if(A[i]==c)
			count++;
		else{
			if(count>0)
				count--;
			else{
				c=A[i];
				count=1;
			}
		}
	if(count>0)
		for(i=count=0;i<n;i++){
			if(A[i]==c)
				count++;
			if(count>n/2)
				return c;
			else
				return -1;
		}
	}
}
找出序列未出现过的最小整数,尽量降低时间复杂度
#include<stdlib.h>
#include <string.h>
int findMissMin(int A[],int n)
{
	int i,*B;
	B=(int *)malloc(sizeof(int)*n);
	memset(B,0,sizeof(int)*n);
	for(i=0;i<n;i++){
		if(A[i]>0&&A[i]<n)
			B[A[i]-1]=1;
		for(i=0;i<n;i++){
			if(B[i]==0)
				return i+1;
		}
	}
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值