顺序表的基本建立,以及增删改查的相关操作(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,轻量级,非常好用。


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



相关文章
|
26天前
|
存储 算法 程序员
【数据结构】C语言实现顺序表万字详解(附完整运行代码)
【数据结构】C语言实现顺序表万字详解(附完整运行代码)
39 0
|
1月前
|
Linux C语言
Linux系统下C语言的队列操作
Linux系统下C语言的队列操作
23 0
|
1月前
|
算法 C语言
【专业解码】递归求和在C语言中的神操作!只需1秒,你也能轻松开挂
【专业解码】递归求和在C语言中的神操作!只需1秒,你也能轻松开挂
|
1月前
|
编译器 C语言
嵌入式C语言变量、数组、指针初始化的多种操作
嵌入式C语言变量、数组、指针初始化的多种操作
31 0
|
2月前
|
C语言
C语言内存及堆栈操作
C语言内存及堆栈操作
18 0
|
3月前
|
C语言
C语言顺序表
C语言顺序表
32 0
|
4月前
|
C语言
三子棋真是太神奇啦~~~C语言三子棋小游戏详解,具体到每一步操作的解释说明,不信你学不会!
三子棋真是太神奇啦~~~C语言三子棋小游戏详解,具体到每一步操作的解释说明,不信你学不会!
43 2
|
1天前
|
存储 算法 C语言
C语言进阶:顺序表(数据结构基础) (以通讯录项目为代码练习)
C语言进阶:顺序表(数据结构基础) (以通讯录项目为代码练习)
|
2天前
|
存储 C语言
C语言中字符串的引用与数组元素操作
C语言中字符串的引用与数组元素操作
12 0
|
1月前
|
存储 C语言
C语言结构体操作
C语言结构体操作
15 0