线性表主要两种结构:
顺序存储 和 链式存储:
这次写的顺序表,指的是线性表的顺序存储模式;
定义类型:
#define ListInitSize 100
#define ListIncrement 10
#define LElemType int
typedef struct Sqlist{
LElemType *base;
int length;
int listsize;
}SqList;
(1)、初始化操作:InitSqList ( &L )
void InitSqList(SqList &L,LElemType InitSize = ListInitSize )
{
L.base=new LElemType [ InitSize ] ;
L.length=0;
L.listsize=InitSize;
}
(2)、判断是否为空表 ListIsEmpty(L)
int ListIsEmpty(SqList L){
return L.length==0?0:1;
}
(3)、求顺序表的长度ListLength(L)
int ListLength(Sqlist &L){
return L.length;
}
(4)、取顺序表中的第i个元素GetElem(L,i,&e)
void GetElem(SqList &L,int i,LElemType &e){
if ( i<1 || i>L.length ) {
printf("GetElem : Index error \n");
return ;
}
e=L.base[i-1];
}
(5)、查找元素e在线性表中的位序LocateElem(L,e)
int LocateElem(SqList L , LElemType e ){
int i = 0 ;
while( i< L.length && e != L.base[i]){
i++;
}
if(i==L.length){
return 0;
}
return i+1;
}
(6)、插入操作ListInsert(&L,i,e)
void ListInsert( SqList &L , int pos , LElemType e ){
int Tmp=L.listsize+ListIncrement;
LElemType* tL;
if(pos<1||pos>L.length+1){
printf("insert index %d .is illegal\n",pos);
printf("error\n");
return ;
}
if(L.listsize==L.length+1){
tL=new LElemType[Tmp];
memcpy(tL,L.base,sizeof(L.base));
L.base=tL;
delete []tL;
L.listsize+=ListIncrement;
}
L.length++;
for(int i=L.length-1;i>pos;i--){
L.base[i]=L.base[i-1];
}
L.base[pos-1]=e;
return ;
}
(7)、删除操作ListDelete(&L,i,&e)
void ListDelete(Sqlist &L , int pos){
if(pos<1||pos>L.length){
printf("ListDelete index : %d illegal \n" , pos);
return ;
}
for(int i=pos-1;i<L.length-1;i++){
L.base[i]=L.base[i+1];
}
L.length--;
return ;
}
调试代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ListInitSize 100
#define ListIncrement 10
#define LElemType int
typedef struct Sqlist{
LElemType *base;
int length;
int listsize;
}SqList;
void InitSqList(SqList &L,LElemType InitSize = ListInitSize )
{
L.base=new LElemType [ InitSize ] ;
L.length=0;
L.listsize=InitSize;
}
int ListIsEmpty(SqList L){
return L.length==0?0:1;
}
int ListLength(Sqlist &L){
return L.length;
}
void GetElem(SqList &L,int i,LElemType &e){
if ( i<1 || i>L.length ) {
printf("GetElem : Index error \n");
return ;
}
e=L.base[i-1];
}
int LocateElem(SqList L , LElemType e ){
int i = 0 ;
while( i< L.length && e != L.base[i]){
i++;
}
if(i==L.length){
return 0;
}
return i+1;
}
void ListInsert( SqList &L , int pos , LElemType e ){
int Tmp=L.listsize+ListIncrement;
LElemType* tL;
if(pos<1||pos>L.length+1){
printf("insert index %d .is illegal\n",pos);
printf("error\n");
return ;
}
if(L.listsize==L.length+1){
tL=new LElemType[Tmp];
memcpy(tL,L.base,sizeof(L.base));
L.base=tL;
delete []tL;
L.listsize+=ListIncrement;
}
L.length++;
for(int i=L.length-1;i>pos;i--){
L.base[i]=L.base[i-1];
}
L.base[pos-1]=e;
return ;
}
void ListDelete(Sqlist &L , int pos){
if(pos<1||pos>L.length){
printf("ListDelete index : %d illegal \n" , pos);
return ;
}
for(int i=pos-1;i<L.length-1;i++){
L.base[i]=L.base[i+1];
}
L.length--;
return ;
}
int main()
{
Sqlist L;
InitSqList(L);
int n,x;
printf("input n : \n");
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&x);
ListInsert(L,L.length+1,x);
}
ListDelete( L , L.length/2);
for(int i=0;i<L.length;i++){
int e,pos;
GetElem(L,i+1,e);
pos=LocateElem(L,e);
printf("序列中第%d个位: %d\n",pos,e);
}
return 0;
}
以上就是线性表-顺序表的基本操作:
7个函数其中有2个其实没有用,因为线性表里面都需要这个函数,所以才出现的。
判断是否为空表,判断是否线性表的长度。
因为只要知道L.length的大小就可以。
例题2-1:将两个按值递增有序的线性表La和Lb合并成一个按值递增有序的线性表Lc,
假设La=(5,9,18,25),Lb=(6,9,12,18,24,39),则Lc=(5,6,9,9,12,18,18,24,25,39)
思路:因为两个线性表都是递增有序的,然后用两个标志位放在两个线性表的前面。
不断移动两个标志位,一直比较,组成一个递增的,最后如果有哪一个剩下来的直接接上去即可。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ListInitSize 100
#define ListIncrement 10
#define LElemType int
typedef struct Sqlist{
LElemType *base;
int length;
int listsize;
}SqList;
void InitSqList(SqList &L,LElemType InitSize = ListInitSize )
{
L.base=new LElemType [ InitSize ] ;
L.length=0;
L.listsize=InitSize;
}
int ListIsEmpty(SqList L){
return L.length==0?0:1;
}
int ListLength(Sqlist &L){
return L.length;
}
void GetElem(SqList &L,int i,LElemType &e){
if ( i<1 || i>L.length ) {
printf("GetElem : Index error \n");
return ;
}
e=L.base[i-1];
}
int LocateElem(SqList L , LElemType e ){
int i = 0 ;
while( i< L.length && e != L.base[i]){
i++;
}
if(i==L.length){
return 0;
}
return i+1;
}
void ListInsert( SqList &L , int pos , LElemType e ){
int Tmp=L.listsize+ListIncrement;
LElemType* tL;
if(pos<1||pos>L.length+1){
printf("insert index %d .is illegal\n",pos);
printf("error\n");
return ;
}
if(L.listsize==L.length+1){
tL=new LElemType[Tmp];
memcpy(tL,L.base,sizeof(L.base));
L.base=tL;
delete []tL;
L.listsize+=ListIncrement;
}
L.length++;
for(int i=L.length-1;i>pos;i--){
L.base[i]=L.base[i-1];
}
L.base[pos-1]=e;
return ;
}
void ListDelete(Sqlist &L , int pos){
if(pos<1||pos>L.length){
printf("ListDelete index : %d illegal \n" , pos);
return ;
}
for(int i=pos-1;i<L.length-1;i++){
L.base[i]=L.base[i+1];
}
L.length--;
return ;
}
void ListOutput(SqList &L){
for(int i=0;i<L.length;i++){
printf("%d%c",L.base[i],i==L.length-1?'\n':' ' );
}
}
int a[]={5,9,18,25};
int b[]={6,9,12,18,24,39};
void MergeList(SqList La,SqList Lb,SqList &Lc)
{
int ia,ib,ta,tb,cnt=0,k=0;
ia=ib=1;
while( ia<=ListLength(La) && ib<=ListLength(Lb) ){
GetElem(La,ia,ta);
GetElem(Lb,ib,tb);
if(ta<=tb){
ListInsert(Lc,++k,ta);
ia++;
}else{
ListInsert(Lc,++k,tb);
ib++;
}
}
while(ia<=ListLength(La)){
GetElem(La,ia,ta);
ListInsert(Lc,++k,ta),ia++;
}
while(ib<=ListLength(Lb)){
GetElem(Lb,ib,tb);
ListInsert(Lc,++k,tb),ib++;
}
}
int main()
{
Sqlist La,Lb,Lc;
InitSqList(La);
InitSqList(Lb);
InitSqList(Lc);
for(int i=0;i<4;i++){
ListInsert(La,La.length+1,a[i]);
}
ListOutput(La);
for(int i=0;i<6;i++){
ListInsert(Lb,Lb.length+1,b[i]);
}
ListOutput(Lb);
MergeList(La,Lb,Lc);
ListOutput(Lc);
}
例题2-2 将两个顺序表合并成一个顺序表,请设计算法实现之
(1)、表中元素有序 ——SetMerge
(2)、表中元素无序——SetUnion / SetUnion_diff
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ListInitSize 100
#define ListIncrement 10
#define LElemType int
typedef struct Sqlist{
LElemType *base;
int length;
int listsize;
}SqList;
void InitSqList(SqList &L,LElemType InitSize = ListInitSize )
{
L.base=new LElemType [ InitSize ] ;
L.length=0;
L.listsize=InitSize;
}
int ListIsEmpty(SqList L){
return L.length==0?0:1;
}
int ListLength(Sqlist &L){
return L.length;
}
void GetElem(SqList &L,int i,LElemType &e){
if ( i<1 || i>L.length ) {
printf("GetElem : Index error \n");
return ;
}
e=L.base[i-1];
}
int LocateElem(SqList L , LElemType e ){
int i = 0 ;
while( i< L.length && e != L.base[i]){
i++;
}
if(i==L.length){
return 0;
}
return i+1;
}
void ListInsert( SqList &L , int pos , LElemType e ){
int Tmp=L.listsize+ListIncrement;
LElemType* tL;
if(pos<1||pos>L.length+1){
printf("insert index %d .is illegal\n",pos);
printf("error\n");
return ;
}
if(L.listsize==L.length+1){
tL=new LElemType[Tmp];
memcpy(tL,L.base,sizeof(L.base));
L.base=tL;
delete []tL;
L.listsize+=ListIncrement;
}
L.length++;
for(int i=L.length-1;i>pos;i--){
L.base[i]=L.base[i-1];
}
L.base[pos-1]=e;
return ;
}
void ListDelete(Sqlist &L , int pos){
if(pos<1||pos>L.length){
printf("ListDelete index : %d illegal \n" , pos);
return ;
}
for(int i=pos-1;i<L.length-1;i++){
L.base[i]=L.base[i+1];
}
L.length--;
return ;
}
void ListOutput(SqList &L){
for(int i=0;i<L.length;i++){
printf("%d%c",L.base[i],i==L.length-1?'\n':' ' );
}
}
int a[]={5,9,18,25};
int b[]={6,9,12,12,18,24,39};
void SetMerge(SqList La,SqList Lb,SqList &Lc)
{
int Len_C=La.length+Lb.length+10;
// 因为可能访问length_c+1的位置,防止越界加10
InitSqList(Lc,Len_C);
int ia,ib,ta,tb,cnt=0,k=0;
ia=ib=1;
while( ia<=ListLength(La) && ib<=ListLength(Lb) ){
GetElem(La,ia,ta);
GetElem(Lb,ib,tb);
if(ta<=tb){
ListInsert(Lc,++k,ta);
ia++;
}else{
ListInsert(Lc,++k,tb);
ib++;
}
}
while(ia<=ListLength(La)){
GetElem(La,ia,ta);
ListInsert(Lc,++k,ta),ia++;
}
while(ib<=ListLength(Lb)){
GetElem(Lb,ib,tb);
ListInsert(Lc,++k,tb),ib++;
}
}
void SetUnion(SqList &La, SqList Lb){//就地处理
// 设两个顺序表La和Lb中的元素无序,将这个表合并成一个表
// 假设La表的存储空间足够大
int Len_a=La.length,i,j;
for(j=0;j<Lb.length ;j++){
for(i=0;i<Len_a;i++){
if(La.base[i]==Lb.base[j]){
break;
}
}
if(i>=Len_a){
La.base[Len_a++]=Lb.base[j];
}
}
La.length=Len_a;
}
void SetUnion_diff(SqList La, SqList Lb,SqList &Lc){//异地处理
// 设两个顺序表La和Lb中的元素无序,将这个表合并成一个表
int Len_c=La.length+Lb.length+2,i,j;
InitSqList(Lc,Len_c);
Len_c=La.length;
memcpy(Lc.base,La.base,sizeof(La.base)*La.length);
ListOutput(Lc);
for(j=0;j<Lb.length ;j++){
for(i=0;i<Len_c;i++){
if(Lc.base[i]==Lb.base[j]){
break;
}
}
if(i>=Len_c){
Lc.base[Len_c++]=Lb.base[j];
}
}
Lc.length=Len_c;
}
int main()
{
Sqlist La,Lb,Lc;
InitSqList(La);
InitSqList(Lb);
for(int i=0;i<4;i++){
ListInsert(La,La.length+1,a[i]);
}
printf("线性表La: \n");
ListOutput(La);
for(int i=0;i<7;i++){
ListInsert(Lb,Lb.length+1,b[i]);
}
printf("线性表Lb: \n");
ListOutput(Lb);
printf("两个有序的线性表合并 : \n");
SetMerge(La,Lb,Lc);
ListOutput(Lc);
printf("两个无序的线性表合并_去重后 集合(就地处理): \n");
SetUnion(La,Lb);
ListOutput(La);
printf("两个无序的线性表合并_去重后 集合(异地处理): \n");
SetUnion_diff(La,Lb,Lc);
ListOutput(Lc);
return 0;
}
例题2-3
顺序表L中的元素递增有序,请设计算法完成最少时间在表中查找数值为X的元素,
若找到将其雨后级元素位置相交换,若找不到将其插入表中元素仍递增有序。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ListInitSize 100
#define ListIncrement 10
#define LElemType int
typedef struct Sqlist{
LElemType *base;
int length;
int listsize;
}SqList;
void InitSqList(SqList &L,LElemType InitSize = ListInitSize )
{
L.base=new LElemType [ InitSize ] ;
L.length=0;
L.listsize=InitSize;
}
int ListIsEmpty(SqList L){
return L.length==0?0:1;
}
int ListLength(Sqlist &L){
return L.length;
}
void GetElem(SqList &L,int i,LElemType &e){
if ( i<1 || i>L.length ) {
printf("GetElem : Index error \n");
return ;
}
e=L.base[i-1];
}
int LocateElem(SqList L , LElemType e ){
int i = 0 ;
while( i< L.length && e != L.base[i]){
i++;
}
if(i==L.length){
return 0;
}
return i+1;
}
void ListInsert( SqList &L , int pos , LElemType e ){
int Tmp=L.listsize+ListIncrement;
LElemType* tL;
if(pos<1||pos>L.length+1){
printf("insert index %d .is illegal\n",pos);
printf("error\n");
return ;
}
if(L.listsize==L.length+1){
tL=new LElemType[Tmp];
memcpy(tL,L.base,sizeof(L.base));
L.base=tL;
delete []tL;
L.listsize+=ListIncrement;
}
L.length++;
for(int i=L.length-1;i>pos;i--){
L.base[i]=L.base[i-1];
}
L.base[pos-1]=e;
return ;
}
void ListDelete(Sqlist &L , int pos){
if(pos<1||pos>L.length){
printf("ListDelete index : %d illegal \n" , pos);
return ;
}
for(int i=pos-1;i<L.length-1;i++){
L.base[i]=L.base[i+1];
}
L.length--;
return ;
}
void ListOutput(SqList &L){
for(int i=0;i<L.length;i++){
printf("%d%c",L.base[i],i==L.length-1?'\n':' ' );
}
}
//顺序表L中的元素递增有序,请设计算法完成最少时间在表中查找数值为X的元素,
//若找到将其雨后级元素位置相交换,若找不到将其插入表中元素仍递增有序。
void SearchElement(SqList &L , LElemType x){
LElemType Low=0,High=L.length-1,flag=0,mid;
while(Low<=High&&!flag){
mid=(Low+High)>>1;
if(x<L.base[mid]){
High=mid-1;
}else if(x==L.base[mid]){
flag=1;
}else{
Low=mid+1;
}
}
if(flag){
if(mid+1>=L.length){
printf("值为x的元素为表中的最后一个元素,没有后继。\n");
}else{
LElemType temp=L.base[mid];
L.base[mid]=L.base[mid+1];
L.base[mid+1]=temp;
}
}else{
int i;
for(i=L.length-1;i>=Low&&L.base[i]>x;i--){
L.base[i+1]=L.base[i];
}
L.base[i+1]=x;
L.length++;
}
}
int main()
{
Sqlist L;
InitSqList(L);
int n,x;
for(int i=0;i<5;i++){
ListInsert(L,L.length+1,i*2);
}
ListOutput(L);
printf("查找 “ 3 ” :\n");
SearchElement(L,3);
ListOutput(L);
printf("查找 “ 4 ” :\n");
SearchElement(L,4);
ListOutput(L);
return 0;
}
例题2-4:假设一组整数(包括正整数和负整数)存储在一个顺序表中,
请设计算法在O(n)的时间范围内将所有的负整数放在所有正整数的前面
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ListInitSize 100
#define ListIncrement 10
#define LElemType int
typedef struct Sqlist{
LElemType *base;
int length;
int listsize;
}SqList;
void InitSqList(SqList &L,LElemType InitSize = ListInitSize )
{
L.base=new LElemType [ InitSize ] ;
L.length=0;
L.listsize=InitSize;
}
int ListIsEmpty(SqList L){
return L.length==0?0:1;
}
int ListLength(Sqlist &L){
return L.length;
}
void GetElem(SqList &L,int i,LElemType &e){
if ( i<1 || i>L.length ) {
printf("GetElem : Index error \n");
return ;
}
e=L.base[i-1];
}
int LocateElem(SqList L , LElemType e ){
int i = 0 ;
while( i< L.length && e != L.base[i]){
i++;
}
if(i==L.length){
return 0;
}
return i+1;
}
void ListInsert( SqList &L , int pos , LElemType e ){
int Tmp=L.listsize+ListIncrement;
LElemType* tL;
if(pos<1||pos>L.length+1){
printf("insert index %d .is illegal\n",pos);
printf("error\n");
return ;
}
if(L.listsize==L.length+1){
tL=new LElemType[Tmp];
memcpy(tL,L.base,sizeof(L.base));
L.base=tL;
delete []tL;
L.listsize+=ListIncrement;
}
L.length++;
for(int i=L.length-1;i>pos;i--){
L.base[i]=L.base[i-1];
}
L.base[pos-1]=e;
return ;
}
void ListDelete(Sqlist &L , int pos){
if(pos<1||pos>L.length){
printf("ListDelete index : %d illegal \n" , pos);
return ;
}
for(int i=pos-1;i<L.length-1;i++){
L.base[i]=L.base[i+1];
}
L.length--;
return ;
}
void ListOutput(SqList &L){
for(int i=0;i<L.length;i++){
printf("%d%c",L.base[i],i==L.length-1?'\n':' ' );
}
}
//假设一组整数(包括正整数和负整数)存储在一个顺序表中,
//请设计算法在O(n)的时间范围内将所有的负整数放在所有正整数的前面
void Divide(SqList &L ){
int Low=0,High=L.length-1;
LElemType tmp;
tmp=L.base[Low];
while(Low<High){
while(Low<High&&L.base[High]>0){
High--;
}
if(Low<High){
L.base[Low]=L.base[High];
Low++;
}
while(Low<High&&L.base[Low]<0){
Low++;
}
if(Low<High){
L.base[High]=L.base[Low];
High--;
}
}
L.base[Low]=tmp;
}
int main()
{
Sqlist L;
InitSqList(L);
int n,x,sign=1;
for(int i=1;i<=5;i++){
sign=-sign;
ListInsert(L,L.length+1,sign*i*2);
}
ListOutput(L);
Divide(L);
ListOutput(L);
return 0;
}
例题2-5:设计算法,将顺序表中的所有元素就地逆置
例题2-5:设计算法,将顺序表中的所有元素就地逆置
#include<stdio.h
>#include<stdlib.h
>#include<string.h
>#define ListInitSize 100
#define ListIncrement 10
#define LElemType int
typedef struct Sqlist{
LElemType *base;
int length;
int listsize;
}SqList;
void InitSqList(SqList &L,LElemType InitSize = ListInitSize ){
L.base=new LElemType [ InitSize ] ;
L.length=0;
L.listsize=InitSize;
}
int ListIsEmpty(SqList L){
return L.length==0?0:1;
}
int ListLength(Sqlist &L){
return L.length;
}
void GetElem(SqList &L,int i,LElemType &e){
if ( i<1 || i>L.length ) {
printf("GetElem : Index error \n");
return ;
}
e=L.base[i-1];
}
int LocateElem(SqList L , LElemType e ){
int i = 0 ;
while( i< L.length && e != L.base[i]){
i++;
}
if(i==L.length){
return 0;
}
return i+1;
}
void ListInsert( SqList &L , int pos , LElemType e ){
int Tmp=L.listsize+ListIncrement;
LElemType* tL;
if(pos<1||pos>L.length+1){
printf("insert index %d .is illegal\n",pos);
printf("error\n");
return ;
}
if(L.listsize==L.length+1){
tL=new LElemType[Tmp];
memcpy(tL,L.base,sizeof(L.base));
L.base=tL;
delete []tL;
L.listsize+=ListIncrement;
}
L.length++;
for(int i=L.length-1;i>pos;i--){
L.base[i]=L.base[i-1];
}
L.base[pos-1]=e;
return ;
}
void ListDelete(Sqlist &L , int pos){
if(pos<1||pos>L.length){
printf("ListDelete index : %d illegal \n" , pos);
return ;
}
for(int i=pos-1;i<L.length-1;i++){
L.base[i]=L.base[i+1];
}
L.length--;
return ;
}void ListOutput(SqList &L){
for(int i=0;i<L.length;i++){
printf("%d%c",L.base[i],i==L.length-1?'\n':' ' );
}
}//设计算法:将顺序表中的所有元素就地逆置void ListReverse(SqList &L){
int Low=0,High=L.length-1;
while(Low<High){
LElemType temp=L.base[Low];
L.base[Low]=L.base[High];
L.base[High]=L.base[Low];
Low++;High--;
}
}void Listreverse(SqList &L){
for(int i=0;i<L.length/2;i++){
LElemType temp=L.base[i];
L.base[i]=L.base[L.length-1-i];
L.base[L.length-1-i]=temp;
}
}int main(){
Sqlist L;
InitSqList(L);
int n,x,sign=1;
for(int i=1;i<=5;i++){
sign=-sign;
ListInsert(L,L.length+1,sign*i*2);
}
ListOutput(L);
Listreverse(L);
ListOutput(L);
return 0;
}