顺序表的基本建立,以及增删改查的相关操作(c语言描述之顺序表)

简介: 一: 顺序表是什么在c语言描述的数据结构里,顺序表是一种线性存储结构。线性存取结构又是什么?我们可以这样理解,线性存取就是将一串具有相同特征的数据用一根线串接起来,然后再放到我们的存储之中。当然,数据结构都是抽象出来的概念,但是这种抽象的理解方式也就掩盖了底层的复杂,也就方便我们去操作内存。二:顺序表与链表的区别

一: 顺序表是什么


在c语言描述的数据结构里,顺序表是一种线性存储结构。线性存取结构又是什么?


我们可以这样理解,线性存取就是将一串具有相同特征的数据用一根线串接起来,然后再放到我们的存储之中。当然,数据结构都是抽象出来的概念,但是这种抽象的理解方式也就掩盖了底层的复杂,也就方便我们去操作内存。


二:顺序表与链表的区别


顺序表是将元素放到一块连续的内存存取空间的。在存取元素数据之前,需要申请一块足够大的内存空间,数据之间是一个挨一个,所以我们说是顺序表,就是按照顺序依次存放。


链表在存放数据之时,什么时候存储数据,什么时候才申请存储空间,数据之间并不是顺序相连,而是链式相连,这条链,我们可以认为是每个元素所包含的指针。每个节点含有一个数据域和指针域,指针域存放了下一个元素的存储位置信息,构成了链。



链式存储是很容易产生碎片化信息的,因为元素前后并不是顺序相连,中间可能会含有部分未使用的空间,所以比较浪费空间,但是顺序表没有这种缺点,含有在空间占用上,肯定是链式存取更加占用空间,除了碎片化的一些东西,还有携带的指针域也会占用一部分的空间,所以内存的空间占用率比较大。


我们考虑具体的操作,我们在查找元素的时候还是顺序存储结构比较方便啦!因为我们直接可以从数组下标访问,很明显,这种查找方式的时间复杂度为o(1),相比之下,链式存储结构的查找方式就是从开始进行遍历,所以时间复杂度是o(n)。


但是呢,链式存储结构总不是一无是处的吧!不然我们还要它干嘛?我们考虑除去查找方式的其它操作,还有插入,删除操作这些,比如我们进行插入操作的时候,在顺序表中进行插入操作的时候,我们在表中插入一个元素,那么后面的元素就都得往后面移动,需要移动大量的元素,但是链表呢,我们通过链式存储结构,就不需要进行大量的移动。


想要了解链表请参考下面这篇博文。具体静态动态,这里都以代码实现了。


单链表的静态建立以及动态链表建立(红芯书院的研学)


三: 顺序表的代码实现操作


现在我们考虑如何实现简简单单的顺序表


偷个懒,我们完全可以写一个数组,说它是顺序表。但是我们为了s更加深刻的理解,我们就还是采用结构体的这种方式。


理一下思路的话,数据储存的话,我们就用数组啦!因为是顺序存储嘛。


我们先看部分的关键代码,我们先看下面这一部分。这里主要显示的是顺序表的结构体存储方式。


#include<stdio.h>
# define MAX 1000
typedef struct Student
{
    /* data */
    int data[MAX]
}stu1;


我们稍微对比一下链表的结构体


#include<stdio.h>
typedef struct Student{
    int age;
    struct Student *next;
}stu1;


我们可以对比到,我们先都把两者的 int 类型的数据age来看,一个是直接先申请了空间的,一个是没有先申请空间。当然,顺序表后面也可以申请空间的,我们这边先不做赘述。还有就是一个没有指针域,一个有指针域。可以说,这些就是两者比较在代码实现上最根本的区别。当然顺序表的组成结构体中我们还可以定义其它的有意义的数据,这个就看这人构造啦!比如用来记录顺序表的元素的计数器,这些都决定不了它是顺序表的本质。所以说,编程不是照搬照做!


甚至我我们在给顺序表空间的时候,我们也可以进行申请函数进行空间申请。我们这边就以数组定长来进行举例,因为比较反应本质,简单易懂。


来了哦!


下面我嗯实现顺序表的各种操作,包括增删改查!


1:我们先创建一个顺序表需要的结构体


typedef struct Student1
{
    int data[MAX];
    int length;//length定义了表的长度,用作记录表长
    /* data */
}Student;//结构体名


2:下面我们初始化表,我们初始化表长为0


chushi(Student *L){
    L->length = 0;//初始化表长为0,因为没有任何元素
    printf("初始化完毕!\n");
}


释疑


当L是指针类型的时候我们用L->data这样的格式引用数据,不是指针类型而是结构体对象类型的时候我们用L.data。我们这样简单的去理解,但是指针结构体这些内部还是有许多学问的。


解释部分内容


你可能会疑惑为什么L前面会加一个*号,有的时候会加,有的时候不加。我要对表进行操作,改变表的时候就会进行再主函数中传入表地址。如果我不对表进行改变的化,我就直接传入变量l,按照结构体的方式进行操作。



3:下面我们创建表(给表添加一些基本的元素)


create(Student * l,int size){
    if(size>MAX){
        printf("超出最大限制长度");
    }
    srand(time(0));//播种
    for(int i =0;i<size;i++){
        l->data[i]=rand()%20+1;
        l->length++;
        //printf("%d\t",l->data[i]);
    }
    //printf("%d",l->length);
    printf("基本创建完毕\n");
 }


释疑


我们用到的不过是随机生成函数,rand()这边,以及srand()函数,用来生成种子。想要了解,可以去问度娘。


4:下面我们进行输出表的部分元素


print(Student L){
     for(int i =0;i<L.length;i++){
         printf("%d\t",L.data[i]);
     }
     printf("元素输出完毕!\n");
 }



5:插入操作的函数


insert(Student *L){
    int n,loc =0;
    printf("请输入插入元素的个数:");
    scanf("%d",&n);
   // printf("执行到此处!");
    if(n>(MAX-L->length)){
         printf("插入元素的个数超出限定的元素个数");
     }
     else 
     {
         printf("执行到此处!");
         for(int i =0;i<n;i++){
            printf("请输入要插入的位置\n:");
            scanf("%d",&loc);
            if((loc>L->length)||(loc<0)){
                printf("不允许这样插入!\n");
            }
            else{
                printf("请输入要插入的元素:\n");
                int ele = 0;
                scanf("%d",&ele);
                for(int j = L->length;j>i-1;j--){
                    L->data[j+1] = L->data[j];//将插入位置的元素以及之后的元素依次往后移动
                }
                L->data[loc-1] = ele;//指定位置将元素插入
                L->length++; //更新表长
            }
         }
     }


6:删除操作函数


delet(Student *L){
     int n =0;
     if(L->length ==0){
         printf("此表为空表,不能再执行删除操作!\n");
     }
     printf("请输入要删除的位置:\n");
     scanf("%d",&n);
     if(n<=0||n>=L->length){
         printf("删除位置不合理!\n");
     }
     else{
        for(int j =n-1;j<L->length;j++){
         L->data[j] =L->data[j+1]; 
        }
         L->length--;
     }
 }


7:进行查询函数


find(Student L){
     int find_1 =0;
     printf("请输入要查找的元素:\n");
     scanf("%d",&find_1);
     for(int i =0;i<L.length;i++){
         if(L.data[i]==find_1){
             printf("已经找到该元素!所在位置为%d\n",i+1);
             break;
         }
         if (i==L.length-1)
         {
             printf("元素没有找到!\n");
             /* code */
         }
     }
    // printf("元素没有查找到!\n");
 }


来看完整的源代码


#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#define MAX 1000
typedef struct Student1
{
    int data[MAX];
    int length;
    /* data */
}Student;
chushi(Student *L){
    L->length = 0;//初始化表长为0,因为没有任何元素
    printf("初始化完毕!\n");
}
create(Student * l,int size){
    if(size>MAX){
        printf("超出最大限制长度\n");
    }
    srand(time(0));//播种
    for(int i =0;i<size;i++){
        l->data[i]=rand()%20+1;
        l->length++;
        //printf("%d\t",l->data[i]);
    }
    //printf("%d",l->length);
    printf("基本创建完毕\n");
 }
 print(Student L){
     for(int i =0;i<L.length;i++){
         printf("%d\t",L.data[i]);
         printf("\n");
     }
     printf("元素输出完毕!\n");
 }
 insert(Student *L){
    int n,loc =0;
    printf("请输入插入元素的个数:\n");
    scanf("%d",&n);
   // printf("执行到此处!");
    if(n>(MAX-L->length)){
         printf("插入元素的个数超出限定的元素个数!\n");
     }
     else 
     {
         printf("执行到此处!\n");
         for(int i =0;i<n;i++){
            printf("请输入要插入的位置:\n");
            scanf("%d",&loc);
            if((loc>L->length)||(loc<0)){
                printf("不允许这样插入!\n");
            }
            else{
                printf("请输入要插入的元素:\n");
                int ele = 0;
                scanf("%d",&ele);
                for(int j = L->length;j>i-1;j--){
                    L->data[j+1] = L->data[j];//将插入位置的元素以及之后的元素依次往后移动
                }
                L->data[loc-1] = ele;//指定位置将元素插入
                L->length++; //更新表长
            }
         }
     }
 }
 delet(Student *L){
     int n =0;
     if(L->length ==0){
         printf("此表为空表,不能再执行删除操作!\n");
     }
     printf("请输入要删除的位置:\n");
     scanf("%d",&n);
     if(n<=0||n>=L->length){
         printf("删除位置不合理!\n");
     }
     else{
        for(int j =n-1;j<L->length;j++){
         L->data[j] =L->data[j+1]; 
        }
         L->length--;
     }
 }
 find(Student L){
     int find_1 =0;
     printf("请输入要查找的元素:\n");
     scanf("%d",&find_1);
     for(int i =0;i<L.length;i++){
         if(L.data[i]==find_1){
             printf("已经找到该元素!所在位置为%d\n",i+1);
             break;
         }
         if (i+1==L.length)
         {
             printf("元素没有找到!\n");
             /* code */
         }
     }
    // printf("元素没有查找到!\n");
 }
int main()
{
    Student l;
    int size=0;
    int n1,loc=0;
    printf("请输入初始化数据元素的个数:\n");
    scanf("%d",&size);
    chushi(&l);
    create(&l,size);
    print(l);
    insert(&l);
    printf("元素插入完毕!\n");
    printf("顺序表新的元素构造如下:\n");
    print(l);
    delet(&l);
    printf("删除完毕!\n");
    printf("顺序表新的构造如下\n");
    print(l);
    find(l);
    system("pause");//防止闪退
}


功能函数都已经写出来了,我们要是想要更加灵活的对标进行操作,可以进行进一步的封装。所用代码编辑器vscode,轻量级,非常好用。


下面看一下整体的代码运行效果



相关文章
|
24天前
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
56 3
|
1月前
|
C语言
链式栈实现(C语言描述)
这篇文章介绍了如何在C语言中实现链式栈,包括节点和栈的创建、入栈、出栈、获取栈顶元素、判断栈是否为空以及销毁栈的操作。
23 1
|
1月前
|
C语言
数组栈的实现(C语言描述)
本文介绍了如何在C语言中使用数组来实现栈的数据结构,包括栈的创建、入栈、出栈、获取栈顶元素、检查栈是否为空、获取栈的大小以及销毁栈等操作,并提供了相应的函数实现。
33 1
|
1月前
|
存储 C语言
探索C语言数据结构:利用顺序表完成通讯录的实现
本文介绍了如何使用C语言中的顺序表数据结构实现一个简单的通讯录,包括初始化、添加、删除、查找和保存联系人信息的操作,以及自定义结构体用于存储联系人详细信息。
21 2
|
1月前
|
C语言
链式顺序表实现(C语言描述)
本文介绍了如何在C语言中实现链式顺序表,包括数据结构的定义、节点的创建、数据的插入和删除以及链表的打印和销毁。
39 2
|
1月前
|
C语言
顺序表数组法构建(C语言描述)
如何使用C语言通过数组方法构建有序顺序表,包括顺序表的创建、插入、删除和打印等。
20 2
|
1月前
|
C语言
无头链表再封装方式实现 (C语言描述)
如何在C语言中实现无头链表的再封装,包括创建节点和链表、插入和删除操作、查找和打印链表以及销毁链表的函数。
27 0
|
1月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
25 0
|
2月前
|
存储 算法 C语言
C语言手撕数据结构代码_顺序表_静态存储_动态存储
本文介绍了基于静态和动态存储的顺序表操作实现,涵盖创建、删除、插入、合并、求交集与差集、逆置及循环移动等常见操作。通过详细的C语言代码示例,展示了如何高效地处理顺序表数据结构的各种问题。
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
35 3