2.2 线性表的顺序存储和实现(C++)

线性表的顺序表示:用一组连续的存储单元依次存储线性表的数据元素。

假设每个数据元素占l个存储单元。

LOC(a(i+1))=LOC(ai)+l

LOC(ai)=LOC(a1)+(i-1)*l     虽然数据元素是从a1开始,但是数据下标从0开始哦

每个元素的存储位置和第一个元素的存储位置的差值都和l成线性关系,知道要查元素的位序,就可以知道存储位置,故是一种随机存取结构。

以下实现是用一维的动态数组。

 

#include <iostream>
#include <string.h>
#include <malloc.h>
using namespace std;

#define ini_len 100
#define add_len 10

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef int elemtype;
//线性表的顺序存储 
typedef struct{
	elemtype *elem;
	int length;
	int listsize;
}Sqlist;

int init(Sqlist *L){
	cout<<"表初始化\n";
	L->elem=(elemtype *)malloc(sizeof(elemtype)*ini_len);//用.会出错 
	if(L->elem==NULL)
		return -1; 
	L->length=0;
	L->listsize=ini_len;
	cout<<"初始化成功!\n";
	return 1;
}
//随机初始化赋值
void  assign(Sqlist *L){
	int i;
	for(i=0;i<10;i++){
		L->elem[i]=i;
		L->length++; 
	} 
}
void show(Sqlist *L){
	int i;
	for(i=0;i<L->length;i++)
		cout<<L->elem[i]<<" ";
}
//按1 位置查找 
int find_loc(Sqlist *L,int loc,elemtype *e){
	if(L==NULL){
		cout<<"此表为空!\n";
		return -1;
	}else{
		loc--;
		if(loc>=0&&loc<=L->length){
			*e=*(L->elem+loc);//两边都是地址,加*取值 
			cout<<*e;
			return 1;
		}
	}
}
//2 按值查找
int find_key(Sqlist *L,elemtype e,int *loc) {
	int flag=0;
	if(L==NULL){
		cout<<"此表为空!\n";
		return -1;
	}else{
		for(int i=0;i<L->length;i++){
			if(L->elem[i]==e){
				*loc=i+1;
				flag=1;
				return 1;
			}
		}
	}
	if(flag==0){
		cout<<"该元素在表中不存在!\n";
		return 1;
	}
}
//3 插入,第i个数据元素之前插入新数据元素x
int insert(Sqlist *L,int i,elemtype x){
	if(L==NULL){
		cout<<"此表为空!\n";
		return -1;
	}else{
		if(i<=1&&i>L->length){
			cout<<"位置不合法!\n";
			return -1;
		}else{
			if(L->length+1>=L->listsize){//看插入的空间够不 
				L->elem=(elemtype *)realloc(L->elem,sizeof(elemtype)*(L->listsize+add_len));
				L->listsize+=add_len;
			}
			int j;
			int len=L->length;
			for(j=len-1;j>=i-1;j--){//第i个元素的下标是i-1 
				L->elem[j+1]=L->elem[j];
			}
			L->length++; 
			L->elem[i-1]=x;//注意是i-1 
			return 1;
		}
	}
} 
//4 删除第i个元素
 int del(Sqlist *L,int i){
	if(L==NULL){
		cout<<"此表为空!\n";
		return -1;
	}else{
		if(i<=1&&i>L->length){
			cout<<"位置不合法!\n";
			return -1;
		}else{
			if(i==L->length){//删除最后一个元素 
				L->length--; 
				return 1;
			}else{
				int j;
				for(j=i-1;j<L->length;j++){//第i个元素的下标是i-1 
					L->elem[j]=L->elem[j+1];//从第i个元素,即下标为i-1的地方,后面的覆盖前面的,故j+1赋给j 
				}
				L->length--;//记得删除后长度减1 
				return 1;
			}
		}
	}
} 
//顺序表的合并,合并后的表装L2里面并且还是有序的 
void merge(Sqlist *L,Sqlist *L1,Sqlist *L2){
	int i=0,j=0,k=0,len,len1,len2;
	len=L->length;
	len1=L1->length;
	while((len+len1)>L2->listsize){
		L2->elem=(elemtype *)realloc(L2->elem,sizeof(elemtype)*(L2->listsize+add_len));
	}
	while(i<len&&j<len1){
		if(L->elem[i]<L1->elem[j]){
			L2->elem[k]=L->elem[i];
			i++;
			k++;
			L2->length++; 
		}else{
			L2->elem[k]=L1->elem[j];
			j++;
			k++;
			L2->length++; 
		}
	}
	if(i<L->length){
		L2->elem[k]=L->elem[i];
		i++;
		k++;
		L2->length++; 
	}
	if(j<L1->length){
		L2->elem[k]=L1->elem[j];
		j++;
		k++;
		L2->length++; 
	}
} 
int main(int argc, char** argv) {
	Sqlist L,L1,L2;//注意是L不是*L 
	int flag;
	int choose;
	flag=init(&L);//传地址过去 
	if(flag==-1){
		cout<<"初始化失败!\n"; 
	}
	assign(&L);
	cout<<"表L"; 
	show(&L);
	cout<<endl;
	
	flag=init(&L1);//传地址过去 
	if(flag==-1){
		cout<<"初始化失败!\n"; 
	}
	assign(&L1);
	cout<<"表L1:";
	show(&L1);
	cout<<endl;
	
	cout<<"\n请对线性表进行操作,按#结束\n";
	cout<<"1 位置查找 \n";
	cout<<"2 按值查找\n";
	cout<<"3 插入,第i个数据元素之前插入新数据元素x\n";
	cout<<"4 删除第i个元素\n";
	cout<<"5 合并两个表\n";
	cout<<"\n";
	cout<<"\n";
	while(1){
		cin>>choose;
		if(choose==-1){
			break;
		}
		switch(choose){
			case 1:
				elemtype e;
				find_loc(&L,3,&e);
				cout<<"第3个位置的值为"<<e<<"\n";
				break;
			case 2:
				int loc;
				find_key(&L,2,&loc);
				cout<<"2的位置是"<<loc<<endl;
				break;
			case 3:
				show(&L);
				cout<<endl;
				insert(&L,6,100);
				show(&L);
				break;
			case 4:
				del(&L,6);
				show(&L);
				break;
			case 5:
				show(&L);
				cout<<endl;
				show(&L1);
				cout<<endl;
				flag=init(&L2);//传地址过去 
				if(flag==-1){
					cout<<"初始化失败!\n"; 
				}
				merge(&L,&L1,&L2);
				show(&L2);
		}
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值