线性表的逻辑特征:至少含一个元素,则只有唯一的开始元素和终端元素,除了开始元素外其他元素有且仅有一个前驱结点

不同实际问题当中,数据元素的类型不同,但同一个线性表当中所有元素具有相同的类型,数据项一样,数据项类型一样

线性表基本运算:

初始化InitList(L) 作用创建一个空表

销毁线性表DestroyLIst(L)释放L内存

求线性表长度

求线性表中第i个元素GetElem(L,i,e)

按值查找位置(L,e)

插入元素:在某个位置插入数据InsElem(L,x,i)

删除元素在某个未知删除元素DelElem(L,e)

输出元素DispList(L)   

 

线性表的存储结构主要分为:顺序存储和链式存储 前者简称为顺序表

线性表相当于一个特殊的数组这个‘数组’拥有一个记录其长度的元素:length 

由于顺序表采用数组存放元素,而数组具有随机存取特性,所以顺序表局有随机存取特性

 

 

 

 

 

 

#include<iostream>
using namespace std;
//定义线性表中数组的长度
#define MaxSize 100
//定义数组类型
typedef int ElemType;
//定义自定义类型结构体
typedef struct{
ElemType data[MaxSize];
int length;
} List;

//初始化线性表
void InitList(List &L){
   L.length=0;
}


//销毁线性表
void DestroryList(List L){}



//获取长度
int GetLength(List &L){
 return L.length;
}



//在某个位置插入元素 函数返回类型为int为了判断是否插入成功
int InsElem(List &L,ElemType a,int r){
 if(r<1||r>L.length+1){
    return 0;
 }
int len=GetLength(L);
 //将r-1到L.length-1的的元素均往后挪一个位置
 for(int i=len;i>r-1;i--){//这里可能相对来说难理解 因为要在逻辑位置r处插入元素 应该将r-1和r-1之后的元素往后挪  L.data[r]=L.data[r-1]
   L.data[i]=L.data[i-1];
 } L.data[r-1]=a;
//插入元素后长度加一
 L.length++;
return 1;
}




//删除某个位置的元素
int DelElem(List &L,int r){
  //判断位置是否正确
  if(r<1||r>L.length){
    return 0;
  }
  //将r-1到L.length-1的元素前移一位 最后执行L.data[L.length-2]=L.data[L.length-1]
  for(int i=r;i<L.length;i++){
    L.data[i-1]=L.data[i];
  }
  L.length--;
  return 1;
}

//返回某个元素的位置

int LocaElem(List &L,ElemType a){
  int i=0;
//这里可以使用while循环或者for循环
  while(L.data[i]!=a&&i<L.length){
    i++;
  }
  //如果循环完了还没找到元素返回0否则返回逻辑序号
  if(i>=L.length){
    return 0;
  }else{
    return i+1;
   }
}


//输出元素
void DisList(List &L){
  if(L.length==0){
    cout<<"当前元素为空";
  }else{
    cout<<"线性表的元素如下:"<<endl;
    for(int i=0;i<L.length;i++){
     cout<<L.data[i]<<" ";
    }
   cout<<endl;
  }
}





//返回某个位置的元素的值
int GetElem(List &L,ElemType a,int r){
  if(r>L.length||r<1){
     return 0;
  }else{
    a=L.data[r];
    return 1;
  }
}

int main(){
/*
实现功能用一个线性表
:初始化InitList
:销毁线性表 DestroryList
:在某个位置插入元素 InsElem
:删除元素DelElem
:返回某个元素的位置LocaElem
:显示元素DisList
:返回长度
:返回地某个位置的元素
*/
//声明线性表
List L;
ElemType a;
//初始化线性表
InitList(L);
//插入元素
cout<<"插入元素1,3,5,12"<<endl;
InsElem(L,1,1);
InsElem(L,3,2);
InsElem(L,5,3);
InsElem(L,12,4);
DisList(L);
cout<<"返回第3个位置的元素"<<endl;
GetElem(L,a,2);
cout<<a<<endl;
cout<<"长度"<<GetLength(L)<<endl;
cout<<"获取元素3的位置"<<endl;
cout<<LocaElem(L,3)<<endl;
cout<<"删除第2个元素"<<endl;
if(DelElem(L,2)){
cout<<"删除成功"<<endl;
}else{
cout<<"删除失败"<<endl;
}
cout<<"输出所有元素"<<endl;
DisList(L);
cout<<"销毁<<endl";
DestroryList(L);

return 0;
}

 


 

结果如下:

 

 

 将上面的顺序表的基本运算分装成一个头文件 48.h

下面使用 注意主函数只能有一个

从r开始删除n个元素

#include "48.h"
//从第r个元素开始删除n个元素
int delElems(List &L,int r,int n){
  //判断参数是否正确
  if(r<1||n<1||r+n-1>L.length){
    return 0;
  }
  //从r+n-1开始向前移动n个位置 注意一个问题   从r开始删除n个元素 实际上逻辑序列删除 r 到 r+n-1 也就是实际顺序 r-1 到r+n-2   r+n-1不删除
  for(int j=r+n-1;j<L.length;j++){
     L.data[j-n]=L.data[j];
  }
  L.length-=n;
  return 1;
}
int main(){
List L;
InitList(L);
InsElem(L,1,1);
InsElem(L,3,2);
InsElem(L,11,3);
InsElem(L,12,4);
InsElem(L,11,5);
InsElem(L,21,6);
InsElem(L,31,7);
InsElem(L,13,8);
InsElem(L,155,9);
InsElem(L,11,10);
InsElem(L,1,7);
InsElem(L,10,4);
DisList(L);
delElems(L,2,5);
DisList(L);

return 0;
}

 

//将所有奇数放到偶数前面
void move(List &L){
  int i=0;
  int j=L.length;
  //一个从前面找偶数 从后面找奇数 当中指导位置重合或者相交
  while(i<=j){
   while(L.data[i]%2==1) i++;
   while(L.data[j]%2==0) j--;
   if(i<j){
     ElemType a=L.data[i];
     L.data[i]=L.data[j];
     L.data[j]=a;
   }
  }
}

解析:

一个从线性表开头开始找偶数 一个从尾巴 开始向前找奇数 当找到时判断此时i 和 j 的位置条件如果满足就交换顺序 一般只有两种情况:

前面的奇数多或者前面的偶数多(将少部分的奇数放到偶数前面)

       

二路归并

 

3.在合并两个有序数组。如图2

      (1) 合并时,有两个指针分别指向有序数组A和B的起始元素,比较指针所指元素的大小,如果A[i]较小,则将A[i]

存入数组C中,并且将i后移。循环比较i和j所指的元素。

      (2)当一个数组A的元素全部排之后,数组B中的指针就并没有指向B的末尾位置,将B中剩余元素全部存入到C中。

//合并两个顺序表到一个线性表当中从小排到大的有序顺序表
void merge(List &L1,List &L2,List &rst){
int i=0;//L1下标
int j=0;//L2下标
int k=0;//rst的下标
while(i<L1.length&&j<L2.length){
if(L1.data[i]>L2.data[j]){
  rst.data[k]=L2.data[j];
  k++;
  j++;
}else if(L1.data[i]<L2.data[j]){
  rst.data[k]=L1.data[i];
  k++;
  i++;
}else{
  rst.data[k]=L1.data[i];
  k++;
  i++;
  rst.data[k]=L2.data[j];
  k++;
  j++;
}
}
//到这一步将剩下的直接放在上面
while(i<L1.length){
  rst.data[k]=L1.data[i];
  k++;
  i++;
}

while(j<L2.length){
  rst.data[k]=L2.data[j];
  k++;
  j++;
}


rst.length=k;
}

 

 

还有一个相似的例子:已知有两个递增有序表A和B 设计算法将A和B的所有公共元素产生一个顺序表C 原理同上

 

 

                                                                                     

posted on 2019-08-09 10:47  渐凸强、啊哈  阅读(558)  评论(0编辑  收藏  举报