数据结构线性表——顺序表(C/C++(类模板))含代码

总结

就是我个人的学习总结。

  • 线性结构分为线性表(一般),栈、队列、串(特殊),数组(推广)
  • 同一线性表中的数据元素必定是具有相同的特性的,即属于同一数据对象,相邻元素间存在序偶关系。
  • 数据表其实就是一个数据对象,由n(n>=0)个数据元素构成的有限序列
  • 线性表可以分为顺序表和链表
  • 顺序表的特点:可随机存取(类似于数组)

C

//动态分配一维数组表示线性表
#include<stdio.h>
#include<stdlib.h>
#define MAX 100     //线性表的存储空间初始分配量
#define IN 10     //存储空间分配增量
typedef struct{
    int *elem;  //基址
    int length; // 表长
    int listsize;   //分配的存储容量,以sizeof(ElemType)为单位
}SqList;

线性表的基本操作实现:
1.初始化(创建)

//创建并初始化线性表
int InitList_Sq(SqList *L){
    (*L).elem=(int*)malloc(IN*sizeof(int));
    if(!(*L).elem)printf("error\n");    //空间分配失败
    (*L).length=0;                     //表长为0
    (*L).listsize=MAX;                  //初始存储容量
    return 0;
}

2.取值
跟据指定的位置序号i,获取表中第i个数据元素的值(就像数组一样通过下标定位获取元素的值)

//取位置i的元素
int GetElem_Sq(SqList L,int i,int *e){
    if(i<1||i>L.length)return 0;
    *e=L.elem[i-1];
    return 1;//返回1代表已经找到了元素,若想要输出元素,需要在加一个输出语句
}

3.查找:
根据指定元素e,查找表中第一个与e相等的元素elem[i],成功后返回i+1.

int LocateElem_Sq(SqList L,int e){
     //在表中查找第一个值与ecompare()的元素的位序
    //如若找到返回其位序,否则返回0
    int i=0;
    int j;
    int *p=L.elem;
    for(;i<L.length;i++){
     if(L.elem[i]==e)
         j=i+1;
 }
    if(i<L.length){
        return j;
    }
    return 0;
}

4.插入:

int ListInsert_Sq(SqList *L,int i,int e){
    int *newbase;
    int *p,*q;
    if(i<1||i>(*L).length)return 0;    //i值不合法
    if((*L).length>=(*L).listsize){//存储空间已满,增加分配
        newbase=(int*)realloc((*L).elem,((*L).listsize+10)*sizeof(int));
        (*L).elem=newbase;//新基址
        (*L).listsize+=10;         //增加存储容量
    }
    q=&(*L).elem[i-1];//插入元素的位置
    p=&(*L).elem[(*L).length-1];
    for(;q<=p;p--){
     *(p+1)=*p;
 }
    *q=e;              //插入
    (*L).length++;        //表长+1
    return 1;
}

5.删除:

int ListDelete_Sq(SqList *L,int i,int *e){
    //删除表中第i个元素,并用e返回其值
    int j;
    int *p,*q;
    if(i<1||i>(*L).length)return 0;//i值不合法
    p=&(*L).elem[i-1];       //p为被删除的位置
    *e=*p;                   //赋值给e
    q=(*L).elem+(*L).length-1;//表尾部元素位置
    while(p<=q){           //元素后移
        *p=*(p+1);
        ++p;
    }
    (*L).length--;   //表长-1
    return 1;
}

6.创建一个线性表(初始化)

void CreateList_Sq(SqList *L,int n){
    printf("输入%d个元素:",n);
    int i=0;
    for(;i<n;i++){
        scanf("%d",&(*L).elem[i]);
    }
    printf("\n");
    (*L).length=n;
}

7.合并两个线性表为一个:

//合并两个线性表为一个线性表
void MargsList_Sq(SqList La,SqList Lb,SqList *Lc){
    //已经知道线性表元素按值非递减顺序排列
    //归并La和Lb得到新的顺序表Lc的元素也是按值非递减排列的
    int *pa;int *pb;int *pc;int *pa_last;int *pb_last;
    pa=La.elem;pb=Lb.elem;
    (*Lc).listsize=(*Lc).length=La.length+Lb.length;
    pc=(*Lc).elem=(int *)malloc((*Lc).listsize*sizeof(int));
    if(!(*Lc).elem)exit;
    pa_last=La.elem+La.length-1;
    pb_last=Lb.elem+Lb.length-1;
    int i=0;
    for(;pa<=pa_last&&pb<=pb_last;pa++,pb++,pc++){
     if(*pa<=*pb){
      *pc=*pa;
      *(++pc)=*pb;
  }
  else{
   *pc=*pb;
   *(++pc)=*pa;
  }           
 } 
}

8.一些简单函数

//判断空表
int ListEmpty_Sq(SqList L){
    return (L.length==0);
}
//表长
int ListLength_Sq(SqList L){
    return L.length;
}
//遍历线性表
int ListTraverse_Sq(SqList L){
    int i;
    for(i=0;i<L.length-1;i++){
        printf("%d  ",L.elem[i]);
    }
    printf("\n");
}

对一些基本操作可以如下主函数检测

int main(){
    SqList L;
    int e;
    int i,a;
    if(InitList_Sq(&L)==0)printf("初始化成功!!!\n");
    if(ListEmpty_Sq(L))
        printf("顺序表为空!\n");
    for(i=0;i<10;i++){
        ListInsert_Sq(&L,i,2*i);
    }
    printf("输出所有元素:");
    ListTraverse_Sq(L);
    printf("输出表长:%d\n",ListLength_Sq(L));
    printf("输出表长是否为空:");
    if(ListEmpty_Sq(L)==1)
        printf("空表!\n");
    else
        printf("非空!\n");
    printf("输出顺序表第3个元素到e:");
    GetElem_Sq(L,3,&e);
    printf("%d\n",e);
    printf("查找元素a");
    scanf("%d",&a);
    printf("元素%d在表中的位置是:%d\n",a,LocateElem_Sq(L,a));
    printf("在表中第4个位置出入%d\n",a+1);
    ListInsert_Sq(&L,4,a+1);
    printf("输出操作后的表:\n");
     ListTraverse_Sq(L);
    printf("删除表中第3个位置的元素:\n");
    ListDelete_Sq(&L,3,&e);
    printf("输出删除的表:\n");
    ListTraverse_Sq(L);
    return 0;
}
        



或者是:

int main(){
    SqList L;
    int e;
    int i,a;
    if(InitList_Sq(&L)==0)printf("初始化成功!!!\n");
    CreateList_Sq(&L,10);
    printf("输出所有元素:");
    ListTraverse_Sq(L);
    printf("输出表长:%d\n",L.length);
    printf("查找元素a");
    scanf("%d",&a);
    printf("元素%d在表中的位置是:%d\n",a,LocateElem_Sq(L,a));
    printf("在表中第4个位置出入%d\n",a+1);
    ListInsert_Sq(&L,4,a+1);
    printf("输出操作后的表:\n");
    ListTraverse_Sq(L);
    printf("删除表中第3个位置的元素:\n");
    ListDelete_Sq(&L,3,&e);
    printf("输出删除的表:\n");
    ListTraverse_Sq(L);
    return 0;
}


合并俩个线性表为一个:

int main(){
    SqList La,Lb,Lc;
    int e;
    int i,a;
    InitList_Sq(&La);
    InitList_Sq(&Lb);
    InitList_Sq(&Lc);
    CreateList_Sq(&La,5);
    CreateList_Sq(&Lb,5);
    printf("输出所有元素:");
    ListTraverse_Sq(La);
    ListTraverse_Sq(Lb);
    printf("输出表长:La=%d\tLb=%d\tLc=%d\n",La.length,Lb.length,Lc.length);
    MargsList_Sq(La,Lb,&Lc);
    printf("输出表长:La=%d\tLb=%d\tLc=%d\n",La.length,Lb.length,Lc.length);
    printf("输出操作后的表:\n");
    ListTraverse_Sq(Lc);
    return 0;
}

C++类(不用模板)

代码:

typedef int DataType;
const int MaxSize=10;          //默认最大表长 
class SqList{
private: 
 DataType *elem;//首地址
 int length;   //实际表长 
 int size;      //最大表长 
public:
 //构造函数(初始化) 
 SqList(){
  size=MaxSize;
  length=0;
  elem=new DataType[size];//分配内存空间
  for(int i=0;i<size;i++){
   elem[i]=NULL;//也可以elem[i]=NULL; 
  } 
 } 
 //析构函数(销毁线性表)
 ~SqList(){
  delete[] elem; //回收内存空间 
 } 
 //基本函数声明
 bool insertelem(DataType Data); //在表尾插入元素 
 bool deleteelem(int location);//删除指定位置处的元素 
 bool changeelem(int location,DataType newData);//修改指定位置处的元素值
 DataType getelem(int location);//返回指定位置处的元素值 
 bool traverseList();//遍历 
 bool createList();//创建 
 int locateElem(DataType Data);//查找元素位置  
 //获取表长
 int lengthlist(){
  return length;
 }    
};
//函数的定义
//在表尾插入新元素
bool SqList::insertelem(DataType Data){
 if(length>=MaxSize){
  cout<<"线性表已满!"<<endl;
  return false;          
 }
 else{
  elem[length]=Data;
  length++;
  return true;
 }
} 
//删除指定位置处的元素
bool SqList::deleteelem(int location){
 if(location<0||location>length){
  cout<<"参数错误!"<<endl;
  return false;
 }
 else{
  for(int i=location-1;i<length;i++){
   elem[i]=elem[i+1];
  }
  length--;
  return true;
 }
} 
//修改指定位置处的元素值
bool SqList::changeelem(int location,DataType newData){
 if(location<0||location>length){
  cout<<"参数错误!"<<endl;
  return false;
 }
 elem[location-1]=newData;
 return true;
} 
//返回指定位置处的元素值 
DataType SqList::getelem(int location){
 if(location>length||location<0){
  cout<<"参数有误!"<<endl;
  return 0; 
 } 
 else{
  return elem[location-1];
 }
}
//遍历
bool SqList::traverseList(){
 for(int i=0;i<length;i++){
  cout<<elem[i]<<'\t';
 }
 cout<<endl;
 return true;
} 
//创建 
bool SqList::createList(){
 int k,n;
 while(1){
  cout<<"输入要输入的元素个数:"<<endl;
     cin>>n;
     if(n<=size){
      break;
  }
     else {
      cout<<"输入的元素个数太大!"<<endl;
      return false;
     }
 } 
 cout<<"输入元素:"<<endl; 
 for(int i=0;i<n;i++){
  cin>>k;
  insertelem(k);
 }
 return true;
} 
//查找元素位置
int SqList::locateElem(DataType Data){
 int k=0;
 for(int i=0;i<length;i++){
  if(elem[i]==Data){
   k=i+1;
   return k;
     }
 }   
    if(k==0)return 0;
}
//将两个非递减的线性表合并为一个线性表
bool MargsList(SqList L1,SqList L2,SqList &L3){
 cout<<"合并两个表为一个表!"<<endl;
 DataType p,q;
 int k=1;
 for(int i=1;i<=L1.lengthlist();i++){
  p=L1.getelem(i);
  for(int j=k;j<=L2.lengthlist();j++){
   q=L2.getelem(j);
   if(p>q){
    k=j+1;
          L3.insertelem(q);
   }
   else {
    k=j;break;
   } 
  }
  L3.insertelem(p);
 }
 return true;
}
//主函数
int main(){
 SqList L1,L2,L3;
 //初始化 
 L1.createList();
 L2.createList();  
 //输出初始化后的顺序表
 L1.traverseList();
 L2.traverseList();  
 //将顺序表索引为5的元素值改为44
 L1.changeelem(5,44);
 L2.changeelem(5,44); 
 //输出修改后的顺序表
 L1.traverseList();
 L2.traverseList(); 
 //将表L1,L2合并得到L3 
 MargsList(L1,L2,L3);
 L3.traverseList();
 return 0;
} 

C++(类模板)

可以看这篇文章了解类模板的基础知识:
https://blog.csdn.net/m0_47484802/article/details/109142448

1.类模板,基本数据结构

#include<iostream>
using namespace std;
/*******线性表的数据结构********/ 
const int defaultSize=10; //设置默认顺序表大小 
template<typename DataType>
class SeqList{
private:
    DataType *elements;      //首地址 
 int maxSize;         //顺序表最大大小 
 int length;          //顺序表的有效长度 
public:
 //构造函数(初始化) 
 SeqList(int size=defaultSize){
  if(size>0){
   maxSize=size;
   length=0; 
   elements=new DataType[maxSize];//分配内存大小 
   for(int i=0;i<maxSize;i++){
    elements[i]=NULL;
   }
  }
 }
 //析构函数
 ~SeqList(){
  delete[] elements; //回收内存空间 
 }  
 //基本操作
 bool insertElement(DataType data);  //在表尾插入新元素
 bool deleteElement(int location);    //删除指定位置的元素 
 DataType getElement(int location);    //获取指定位置的元素 
 bool changeElement(int location,DataType newData);//修改指定位置处的元素值  
 int getLength(){//获取表长 
  return length;
 };
} ;

2.基本操作

//在表尾插入新元素
template<typename DataType> bool SeqList<DataType>::insertElement(DataType data){
 int currentIndex=length;//记录新元素的插入位置
 if(length>maxSize){
  return false;//表满 
 } 
 else{
  elements[currentIndex]=data;// 将新元素插入表尾
  length++;//表长加1
  return true; 
 } 
} 
 //删除指定位置的元素
template<typename DataType> bool SeqList<DataType>::deleteElement(int location){
 if(location>=length||location<0){
  return false; //判断位置是否合法 
 }
 for(int i=location;i<length;i++){
  elements[i]=elements[i+1];//从location位置开始,后一个依次覆盖前一个 
 } 
 length--;//表长减1
 return true; 
}
//获取指定位置的元素值
template<typename DataType> DataType SeqList<DataType>::getElement(int location){
 if(location>=length||location<0){
  cout<<"参数无效!\n" ;
  return false;//判断位置是否合法 
 }
 return elements[location]; //返回指定元素 
} 
//修改指定位置的元素值
template<typename DataType>bool SeqList<DataType>::changeElement(int location,DataType newData){
 if(location<0||location>=length){
  cout<<"参数无效!"<<endl;  //判断位置是否合法 
  return false; 
 }
 elements[location]=newData; //赋值 
 return true;
}

3.主函数实现

//主函数 
int main(){
 SeqList<int> list(10); //建立顺序表
 for(int i=0;i<10;i++){
  list.insertElement(i*10); //插入数据实现初始化 
 } 
 //输出初始化后的顺序表
 for(int i=0;i<list.getLength();i++){
  cout<<list.getElement(i)<<'\t';
 }
 cout<<endl;
 //将顺序表索引为5的元素值改为44
 list.changeElement(5,44);
 //输出修改后的顺序表
 for(int i=0;i<list.getLength();i++){
  cout<<list.getElement(i);
  cout<<'\t';
 } 
 cout<<endl;
 return 0;
}
  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值