【数据结构】一、顺序表的基本操作(C语言)

顺序表的定义、初始化、创建、打印、按值查找、插入(时间复杂度为O(n))、删除(时间复杂度为O(n))、销毁、合并两个顺序表

#include <stdio.h>
#include <stdlib.h>    //malloc函数会用到此头文件

#define MAX 30;//顺序表元素个数最大为30

//函数声明
void initlist(Sqlist* L);    //初始化顺序表
void createlist(Sqlist* L);    //创建顺序表
void printlist(Sqlist* L);    //打印顺序表
void insertlist(Sqlist* L, int pos, Elemtype e);    //插入操作
void deletlist(Sqlist* L, int pos, Elemtype e);    //删除操作

typedef int Elemtype;    //将Elemtype定义为int类型

//顺序表的定义
typedef struct{
    Elemtype* elem;    //顺序表的元素
    int length;    //顺序表的长度
}Sqlist;    //将Sqlist定义为结构体类型,里面定义了顺序表元素和顺序表的长度两个成员


//初始化顺序表
void initlist(Sqlist* L)
{
    L->elem = (Elemtype*)malloc(sizeof(Elemtype)*MAX);//sizeof(Elemtype)算每个元素大小再*MAX就是整个顺序表的大小,(Elemtype *)表示开辟空间来存什么类型的数
    L->length = 0;    //将顺序表的长度设为0,因为是空表
}
//总结初始化顺序表:
//1.给顺序表分配空间
//2.将表长设为0



//用户输入数据创建顺序表
void createlist(Sqlist* L)
{
    int i,n;
    printf("请输入存放的元素个数:");
    scanf("%d",&n);
    printf("请输入一组数字存到顺序表中:");
    for(i = 0;i < n; i++)
    {
        scanf("%d",&L->elem[i]);    //将输入直接存放到顺序表中
        L->length++;    //每放一个元素,表长+1
    }
}
//总结创建顺序表:
//1.用户输入顺序表的元素个数
//2.用户依次输入顺序表的元素,存入顺序表中
//3.表长+1



//打印顺序表
void printlist(Sqlist* L)
{
    int i;
    for(i = 0; i < L->length; i++)
    {
        printf("%d ",L->elem[i]);
    }
}



//按值查找
void searchlist(Sqlist* L, Elemtype e)
{
    int i;
    for(i = 0; i < L->length; i++)
    {
        if(L->elem[i] == e)
        {
            printf("找到了,下标是%d", i);
        }
    }
}

插入元素:

//插入元素
void insertlist(Sqlist* L, int pos, Elemtype e)//在第pos位置插入元素e,pos是元素的下标
{
    int len = L->length;    //将表长(也就是元素个数)用变量len表示,方便后续书写
    int i;
    if((pos>=0) && (pos < len))    //判断插入位置是否合法,必须插入存放着有元素的下标的位置    
        {
            if(len < MAX)    //判断顺序表元素个数是否已满最大值,已经满了就不能插入元素了
            {
                for(i = len-1; i >= pos; i--)
                {
                    L->elem[i+1] = L->elem[i] //将前一个元素放入后一个下标位置中
                }
                L->elem[pos] = e;    //将要插入的元素插入第pos位置
                L->length++;    //增加元素后,表长+1
            }
        }
}
//总结插入元素:
//1.判断插入位置是否合法
//2.判断表是否已占满
//3.从最后一个元素开始,每次将一个元素向后移动一个位置(其本质是复制元素的值)
//4.将新元素插入指定位置
//5.表长+1

删除元素:

//删除元素
void deletlist(Sqlist* L, int pos, Elemtype e)
{
    int len = L->length;
    int i;
    if((pos >= 0) && (pos < len))
    {
        for(i = pos+1; i < len; i++)
        {
            //将后一个元素放入前一个下标位置中
            L->elem[i-1] = L->elem[i]; //这句第一次写的时候错了,记住是第i个赋值给i-1个
        }
        L->length--;    //删除元素后,表长-1
    }
}
//总结删除元素:
//1.判断删除位置是否合法
//2.从删除指定元素的位置+1开始,将后面的元素每次向前移动一个位置(其本质是复制元素的值)
//3.表长-1

销毁顺序表:

//销毁顺序表
void destorylist(Sqlist* L)
{
    if(L->elem)    //顺序表中存在元素才能销毁
    {
        free(L->elem);    //将空间释放
        L->elem = NULL;  //释放后一定要置为空指针
    }
    L->length = 0;    //表长设为0
}

合并两个顺序表:

新表中可以有重复的数字

 依次取出表A中的一个元素和表B的一个元素比较,哪个元素值小,则将这个元素放到表C的表尾

//将A、B表合并为新表C
void Union(Sqlist A, Sqlist B, Sqlist& C)
{
    //新表C的表长就是A表+B表的表长
    C.length = A.length + B.length;
    //给表C分配内存空间
    C.elem = (int*)malloc(C.length);
    
    //pa、pb、pc分别指向对应的表的第一个元素
    int* pa = A.elem;
    int* pb = B.elem;
    int* pc = C.elem;
    //lasta、lastb分别指向对应的表的最后一个元素
    int* lasta = A.elem + (A.length - 1);
    int* lastb = B.elem + (B.length - 1);

    //判断是否到了表尾,到了表尾退出循环
    while (pa <= lasta && pb <= lastb)
    {
        //A表的元素小于B表的元素,就将A表的元素插入新表里
        if (*pa < *pb)
        {
            //将A表的元素赋值给新表
            *pc = *pa;
            //pa指向下一个元素
            pa++;
            //pc指向下一个元素
            pc++;
            //增加元素后,C表长+1
            C.length++;
        }
        else
        {
            //将B表的元素赋值给新表
            *pc = *pb;
            //pb指向下一个元素
            pb++;
            //pc指向下一个元素
            pc++;
            //增加元素后,C表长+1
            C.length++;
        }
    }

    //A表到了表尾,就将B表剩余元素给C表
    if (pa = lasta)
    {
        while (pb <= lastb)
        {
            //将B表的元素赋值给新表
            *pc = *pb;
            //pb指向下一个元素
            pb++;
            //pc指向下一个元素
            pc++;
            //增加元素后,C表长+1
            C.length++;
        }
    }
    //B表到了表尾,就将A表剩余元素给C表
    else
    {
        while (pa <= lasta)
        {
            //将A表的元素赋值给新表
            *pc = *pa;
            //pa指向下一个元素
            pa++;
            //pc指向下一个元素
            pc++;
            //增加元素后,C表长+1
            C.length++;
        }
    }
    
}

顺序表的优点:1.方法简单,容易实现。2.不用为表示结点间的逻辑关系而增加额外的存储开销(因为是顺序存取的)。3.可按序号随机存取顺序表中的数据元素。

顺序表的缺点:1.插入、删除操作时,平均移动大约表中一半的元素,效率较低。2.需要预先分配存储空间,如果预先分配的空间较大会造成空间浪费,预先分配的空间过小又会造成数据溢出。3.顺序表的存储属于静态存储形式,数据元素的个数不能自由扩充。

  • 16
    点赞
  • 178
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值