数据结构——线性结构总结

本文总结了数据结构中的线性结构,包括线性表、栈和队列的特性及操作。介绍了C++中线性表的顺序存储和链式存储,以及vector、list、stack、queue和deque等STL容器的基本操作,并提供了相关习题和解答。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据结构——线性结构总结


写在前面

数据元素的存储(顺序存储和链式存储)和数据元素的操作(插入和删除)是数据结构的重要部分。
数据结构中的线性结构可分为线性表,栈和队列。对于这三种结构,有两种存储方式顺序存储和链式存储以两种主要操作,插入和删除。不同线性结构的插入和删除操作的方式不同,而且不同存储方式在插入和删除的效率上也有所不同。本文就这三种结构x两种存储x两种操作来进行总结,并附上几道相关习题。


线性结构的特点

线性结构的特点是:在数据元素的非空有限集中,
(1)存在惟一的一个被称作“第一个”的数据元素和惟一的一个被称作“最后一个”的数据元素;
(2)除第一个之外,集合中的每个数据元素均只有一个前驱;除最后一个之外,集合中的每一个数据元素均只有一个后继。

线性表

线性表简单来说就是数据元素的非空有限序列,其特点是可以从表中的任何位置进行插入([0 , n])和删除([0 , n-1])操作。本文利用C++实现了线性表的初始化,查找,插入和删除操作,直接附代码如下:

  • 顺序存储
#define MAX_SIZE 100
typedef int ElementType;
typedef struct sqlist{
    ElementType *elem;  //存储空间的基地址
    int length;      //当前长度
    int listsize;     //当前存储空间的大小
}Sqlist;
int init(Sqlist &L) // 初始化
{
    L.elem = (ElementType*)malloc(MAX_SIZE*sizeof(ElementType));
    if(!L.elem) exit(0);
    L.length=0;
    L.listsize = MAX_SIZE;
    return 1;
}
int inser(Sqlist &L, int i, ElementType e) //插入操作
{
    //i的合法值是[0,length]
    //i的意思表示在第i个位置之前插入新元素,i=length时表示在list末尾插入新元素
    if(i<0||i>L.length)return 0;
    if(L.listsize<=L.length)
    {
        ElementType *newbase = (ElementType*)realloc(L.elem,((MAX_SIZE+L.listsize)*sizeof(ElementType)));
        if(!newbase)exit(0);
        L.elem = newbase;
        L.listsize +=MAX_SIZE;
    }
    for(int j=L.length;j>i;j--)L.elem[j]=L.elem[j-1];
    L.elem[i] = e;
    L.length++;
    return 1;
}

int delet(Sqlist &L,int i,ElementType &e)
{
    //删除第i个位置上的元素并用e返回其值
    //i的合法值是[0,length-1]
    if(i<0||i>L.length-1)return 0;
    e = L.elem[i];
    for(int j=i;j<L.length-1;j++)L.elem[j]=L.elem[j+1];
    L.length--;
    return 1;
}
int cmpEqual(ElementType a, ElementType b)
{
    return a==b;
}
int cmpGreat(ElementType a, ElementType b)
{
    return a>b;
}
int cmpLess(ElementType a, ElementType b)
{
    return a<b;
}
int fin(Sqlist &L, ElementType e,int (*cmp)(ElementType, ElementType))
{
    //查找L中第一个与e满足cmp关系的元素的位序[0,length-1],如果没有则返回-1
    //cmp是比较函数,如果满足cmp的比较条件则返回1,否则返回0
    int i=0;
    for(i=0;i<L.length;i++)
    {
        if((*cmp)(L.elem[i],e))return i;
    }
    return -1;
}
  • 链式存储
typedef int ElementType;
typedef struct Lnode{
    ElementType data;
    Lnode* next;
}Lnode, *Lnodelist;

void createList(Lnodelist &l,int n)
{
    /*通过控制台的输入,创建大小为n的链表
    两种创建方式,头插法创建的链表和输入顺序相反,尾插法创建的链表和输入顺序相同*/
    l = (Lnode*)malloc(sizeof(Lnode));
    l->next=NULL;
    Lnode *p;
    /*
    Lnode *q = l;
    for(int i=0;i<n;i++)//尾插法
    {
        p = (Lnode*)malloc(sizeof(Lnode));
        cin>>p->data;
        p->next = q->next;
        q->next = p;
        q = p;
    }
    */
    for(int i=n;i>0;i--) //头插法
    {
        p=(Lnode*)malloc(sizeof(Lnode));
        cin>>p->data;
        p->next=l->next;
        l->next = p;
    }
}
int getElem(Lnodelist &l,int i,ElementType&e)
{
    /*返回单链表中第i个元素,i的取值范围是[1,n];*/
    Lnode *p= l->next;
    int j=1;
    while(p&&j<i)
    {
        p=p->next;
        j++;
    }
    if(!p||j>i)return 0; /*此处判断j>i的原因是,如果传入的i小于1时能够及时报错。*/
    e = p->data;
    return 1;
}
int listInser(Lnodelist &l,int i,ElementType e)
{
    /*在链表第i个位置之前插入元素e,i的取值范围[1, n]*/
    Lnode *p = l,*newP;
    int j=0;
    while(p&&j<i-1)
    {
        p=p->next;
        j++;
    }
    if(!p||j>i-1)return 0; /*此处判断j>i-1的原因是,如果传入的i小于1时能够及时报错。*/
    newP = (Lnode*)malloc(sizeof(Lnode));
    newP->data = e;
    newP->next = p->next;
    p->next = newP;
    return 1;
}
int listDel(Lnodelist &l,int i,ElementType &e)
{
    /*删除链表中第i个元素,并用e返回其值,i的取值范围是[1, n]*/
    Lnode *p= l,*q;
    int j=0;
    while(p->next&&j<i-1)
    {
        p = p->next;
        j++;
    }
    if(!p->next||j>i-1)return 0;/*此处判断j>i-1的原因同上*/
    q = p->next;
    p->next = q->next;
    e =q->data;
    free(q);
    return 1;
}

栈的结构特点是,仅在栈顶(表尾)进行插入和删除操作。栈可以说是操作受限的线性表。栈中元素的修改是按后进先出(LIFO)的原则进行的,所以又称后进先出的线性表。
- 顺序栈

#define STACK_SIZE 100
typedef int SelemType;
typedef struct Stack{
    SelemType *base; //存放数据的数组
    SelemType *top; //栈顶指针,指向栈顶元素上面的地址
    int stacksize; //栈的大小
}Sqstack;
int initS(Sqstack &s)
{
    s.base = (SelemType*)malloc(STACK_SIZE*sizeof(SelemType));
    if(!s.base)exit(0);
    s.top=s.base;
    s.stacksize = STACK_SIZE;
    return 1;
}
int getTop(Sqstack &s,SelemType &e)
{
    //如果不是空栈,则将栈顶元素返回到e,并返回1,否则返回0
    if(s.top==s.base)return 0;
    e = *(s.top-1);
    return 1;
}
int push(Sqstack &s,SelemType e)
{
    //元素e入栈,成功则返回1
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值