数据结构之顺序线性表

首先先说下什么是线性表。线性表是最简单的一种数据结构。通俗的来讲,一个线性表就是以n个数据元素的有限序列(相当于数学中的“有限个元素的数列”)。当n=0时,线性表是空表。
线性结构的特点
<1>:除第一个数据元素以外,每个数据元素都有前驱。
<2>:除最后一个数据元素以外,每个数据元素都有后继。
<3>:除以上两点外,每个数据元素都只有一个前驱和后继。
其次线性表的优缺点
优点:访问某个位置的数据元素比较方便。
缺点:数据元素的插入和删除比较麻烦。时间复杂度也比较高。
现在来看一下怎么实现的。
先了解下其中的宏定义,以后的数据结构中也会用到同样的名称。

#define TRUE   1  
#define FALSE   0  
#define OK    1  
#define ERROR   0  
#define INFEASIBLE -1  
#define OVERFLOW -2  
typedef int Status;

好了,现在才刚刚开始。
以下代码都是用C语言实现的。
首先是—–线性表的动态分配顺序存储结构——-

#define LIST_INIT_SIZE 100 //线性表初始空间分配量  
#define LISTINCREMENT   10 //线性表空间分配的增量 
typedef int ElemType; //这里用整型数据类型代替其他数据类型
typedef struct LNode
{  
    ElemType  *elem;        //存储空间的基地址  
    int      lenght;        //当前的长度  
    int      listsize;      //当前分配的存储容量  
}SqList;   

接下来是创建一个空的线性表:

Status Listinit(SqList &L)
{   
    L.elem = (ElemType *)malloc( LIST_INIT_SIZE * sizeof(ElemType));  
    if(!L.elem) exit(OVERFLOW);  //分配存储空间失败  
    L.lenght = 0;                //初始空表长度为0  
    L.listsize = lenght ;//初始存储容量为100  
    return OK;  
}  

然后是对顺序线性表的插入进行的操作:

Status ListInsert(SqList &L, ElemType e, int i)
{  
    ElemType *p,  *q;  
    if(i<=0 ||i > L.lenght+1) return ERROR;  //i值不合法  
    if (L.lenght >= L.listsize)
     {  
        ElemType *newbase = (ElemType *)realloc(L.elem ,(L.listsize +LISTINCREMENT)*sizeof(ElemType));  
        if(!newbase) return OVERFLOW;   //存储分配失败    
        L.elem = newbase;               //新基值  
        L.listsize += LISTINCREMENT;    //增加存储容量  
    }  
    q = &L.elem[i-1];                     //q为插入的位置  
    for (p = &L.elem[L.lenght]; p>=q; --p) 
    {  
        *p = *(p-1);                    //i元素之后的元素往后移动  
    }  
    *q = e;                             //插入e  
    L.lenght +=1;  
    return OK;  

}  

嗯,看的可能有点不耐烦了,什么乱七八糟的变量名,其实我也不适应。然而需要学习这么课程所以还是耐心点看下去把。
删除操作也很简单直接上代码把

Status ListDelete(SqList &L, int i, ElemType &e)
{  
    int *p,  *q;  //Status相当于int还是不太习惯写。
    if(i<1 ||i > L.lenght) return ERROR;  //i值不合法 ,超过了线性表的长度或者在第一个元素前面当然就是不合法了。
    q = &L.elem[i-1];                    //被删除元素的位置为i,i从0开始的所以是i-1;
    e = *q;                               //被删除元素的值赋值给e  
    for (p = q; p< (L.elem + L.lenght-1);p++)
    { //元素左移  
        *(p)=*(p+1);
    }  
    L.lenght--;
    return OK;  
}  

接着看下对线性表中某个元素的查找

int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType))//这里是一个指针函数,传参数时只需要穿函数名就行 
{
    int i=0;
    ElemType *p=L.elem;
    while(i<L.lenght&&!(*compare)(*p++,e))++i;
    if(i<L.lenght)return i+1;//因为从0开始的所以是i+1; 
    else 
    return 0; 
} 
int compare(ElemType x,ElemType y)//两个数相等的函数 
{
    return x==y; 
}

最后一个合并两个线性表开不开心,终于要结束了。

void mergeList(SqList La, SqList Lb,  SqList &Lc)
{  
    int *pa, *pb, *pc; //ElemType一样的。
    Lc.listsize =  La.lenght + Lb.lenght;  
    initList(Lc, Lc.listsize);          //初始化LC\pc = Lc.elem;  
    Lc.lenght = Lc.listsize;  
    pc = Lc.elem;  
    pa = La.elem;  
    pb = Lb.elem;  
    while (pa <= &La.elem[La.lenght -1] && pb <= &Lb.elem[Lb.lenght -1])
    {  
        if (*pa <= *pb) *pc++ = *pa++;  
        else *pc++ = *pb++;  
    }  
    while(pa <= &La.elem[La.lenght -1]) *pc++ = *pa++; //插入La的剩余元素  
    while(pb <= &Lb.elem[Lb.lenght -1]) *pc++ = *pb++; //插入Lb的剩余元素  

}  

基本操作就基本结束了。接下来放一份完整的代码,仅供参考:

#include <stdio.h>  
#include<stdlib.h>
#include<iostream>
using namespace std;
//宏定义  
#define TRUE   1  
#define FALSE   0  
#define OK    1  
#define ERROR   0  
#define INFEASIBLE -1  
#define OVERFLOW -2   
#define LT(a,b)   ((a)<(b))  
#define N = 100         

#define LIST_INIT_SIZE 100 //线性表初始空间分配量  
#define LISTINCREMENT   10 //线性表空间分配的增量  

typedef int Status;  
typedef int ElemType;  

typedef struct LNode
{  
    ElemType  *elem;        //存储空间的基地址  
    int      lenght;        //当前的长度  
    int      listsize;      //当前分配的存储容量  
}SqList;  

//构造空的线性表 
Status Listinit(SqList &L)
{   
    L.elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));  
    if(!L.elem) exit(OVERFLOW);  //分配存储空间失败  
    L.lenght = 0;                //初始空表长度为0  
    L.listsize = LIST_INIT_SIZE  ;//初始存储容量为100  
    return OK;  
}  
//对顺序线性表的插入进行的操作:
Status ListInsert(SqList &L, ElemType e, int i)
{  
    ElemType *p,  *q;  
    if(i<=0 ||i > L.lenght+1) return ERROR;  //i值不合法  
    if (L.lenght >= L.listsize)
     {  
        ElemType *newbase = (ElemType *)realloc(L.elem ,(L.listsize +LISTINCREMENT)*sizeof(ElemType));  
        if(!newbase) return OVERFLOW;   //存储分配失败    
        L.elem = newbase;               //新基值  
        L.listsize += LISTINCREMENT;    //增加存储容量  
    }  
    q = &L.elem[i];                     //q为插入的位置  
    for (p = &L.elem[L.lenght-1]; p>=q; --p) 
    {  
        *p = *(p-1);                    //i元素之后的元素往后移动  
    }  
    *q = e;                             //插入e  
    L.lenght +=1;  
    return OK;  

}  
//线性表的删除操作: 
Status ListDelete(SqList &L, int i, ElemType &e)
{  
    int *p,  *q;  //Status相当于int还是不太习惯写。
    if(i<1 ||i > L.lenght) return ERROR;  //i值不合法 ,超过了线性表的长度或者在第一个元素前面当然就是不合法了。
    q = &L.elem[i-1];                    //被删除元素的位置为i,i从0开始的所以是i-1;
    e = *q;                               //被删除元素的值赋值给e  
    for (p = q; p< (L.elem + L.lenght-1);p++)
    { //元素左移  
        *(p)=*(p+1);
    }  
    L.lenght--;
    return OK;  
}  
//在线性表中查找某个元素 
int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType))//这里是一个指针函数,传参数时只需要穿函数名就行 
{
    int i=0;
    ElemType *p=L.elem;
    while(i<L.lenght&&!(*compare)(*p++,e))++i;
    if(i<L.lenght)return i+1;//因为从0开始的所以是i+1; 
    else 
    return 0; 
} 
int compare(ElemType x,ElemType y)//两个数相等的函数 
{
    return x==y; 
}
//合并两个线性表 
void mergeList(SqList La, SqList Lb,  SqList &Lc)
{  
    int *pa, *pb, *pc; //ElemType一样的。
    Listinit(Lc);          //初始化LC\pc = Lc.elem;  
   // Lc.lenght = Lc.listsize;  
    Lc.lenght=La.lenght + Lb.lenght;  
    pc = Lc.elem;  
    pa = La.elem;  
    pb = Lb.elem;  
    while (pa <= &La.elem[La.lenght -1] && pb <= &Lb.elem[Lb.lenght -1])
    {  
        if (*pa <= *pb) *pc++ = *pa++;  
        else *pc++ = *pb++;  
    }  
    while(pa <= &La.elem[La.lenght -1]) *pc++ = *pa++; //插入La的剩余元素  
    while(pb <= &Lb.elem[Lb.lenght -1]) *pc++ = *pb++; //插入Lb的剩余元素  

}  
int main()
{
    SqList  La,Lb,Lc;  
    ElemType e;  
    int init,i;  
    Listinit(La);  
    printf("请输入要输入的元素个数:\n");
    scanf("%d",&La.lenght);
    for(int i=0;i<La.lenght;i++)//事例先输入10个数,大小可以自己更改 
    {
        scanf("%d",&La.elem[i]);
    }
    for(int i=0;i<La.lenght;i++)
    {
        printf("%d ",La.elem[i]);//输出顺序线性表 
    }
    cout<<endl;
    printf("请输入要查找的元素\n");
    int u; 
    scanf("%d",&u);
    int z=LocateElem(La,u,compare);//查找元素2是否在该线性表中 
    if(z) 
    printf("查找的元素在第%d个位置上\n",z);
    else
    printf("该线性表中不存在该元素\n"); 
    int mi,w;
    printf("请输入要插入的元素和位置\n"); 
    scanf("%d%d",&mi,&w);
    int flag=ListInsert(La,mi,w);//在第w个位置插入一个数据元素 mi
    if(flag)
    printf("插入成功\n");
    else
    printf("插入失败\n"); 
    for(int i=0;i<La.lenght;i++)
    {
        printf("%d ",La.elem[i]);//输出插入后的顺序线性表 
    }
    printf("\n"); 
    int m,k;//被删除的元素赋给m 
    printf("请输入要删除的元素\n");
    scanf("%d",&k);
    ListDelete(La,k,m);
    for(int i=0;i<La.lenght;i++)
    {
        printf("%d ",La.elem[i]);
    }
    printf("\n%d元素已经被删除\n",m);
    Listinit(Lb);
    printf("请输入另一个线性表的元素个数\n");
    scanf("%d",&Lb.lenght);
    for(int i=0;i<Lb.lenght;i++)//输入另一个顺序线性表 
    {
        scanf("%d",&Lb.elem[i]);
    } 
    for(int i=0;i<Lb.lenght;i++)
    {
        printf("%d ",Lb.elem[i]);//输出另一个顺序线性表 
    }
    printf("\n");
    mergeList(La,Lb,Lc);//合并两个线性表 
    printf("输出合并后的线性表的长度\n");
    for(int i=0;i<Lc.lenght;i++)//输出两个线性表 
    {
        printf("%d ",Lc.elem[i]);
    }
    return 0;
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值