数据结构(C语言)—线性表中顺序表的基本操作以及实现

一、什么叫做顺序表,顺序表通过什么来体现?

        顺序表就是两个在逻辑上相邻的元素,在顺序表中他们的位置也相同。字母A-Z就是一个顺序表。顺序表是由一个个的元素组成的,并且这些元素的类型是相同的。

        我们可以用一个数组来表示这个顺序表,也就是在创建顺序表之前,我们可以给它一个固定大小的空间。

二、我们可以先想一下与顺序表相关的操作可以有哪些,或者是我们可以实现哪些操作?

        1、初始化顺序表

        2、打印输出顺序表

        3、向顺序表中插入元素

        4、在顺序表中删除元素

        5、在顺序表中查找值为X的下标

        6、在顺序表中查找第i个元素的值

        7、获取当前顺序表的长度,即存放元素的数组的长度。

注意:这些东西大家不要死记硬背,理解是如何实现这些操作的即可。

三、按照以上列出来的操作,我们给这些操作分别定义一个函数进行实现。

(一)定义一个结构体:

       在我看来,数据结构的意思就是我们在拿到一个问题时,可以定义一个关于这个问题的结构体。比如顺序表,那我们需要一个数组来存储元素,我们还需要记录当前的元素有多少,也就是数组的长度。所以我们可以定义以下这个结构体:

#define MaxSize 10  //
typedef int ElemType//将int类型重新命名为ElemType,即ElemType可以代替int
typedef struct {
	ElemType data[MaxSize];//定义一个ElemType类型的数组,数组名为data,数组大小为MaxSzie
	int length;//顺序表的当前长度
}SqList;

 (二)初始化顺序表,顺序表进行初始化,我们只需要将当前这个顺序表的长度等于0即可,表示当前顺序表中没有东西,而不像是链表中那样标记指针为空。代码如下:

//初始化顺序表
void InitSq(SqList *L)
{
    L->length=0;
    printf("初始化之后,数组的长度为:%d\n",L->length);//输出顺序表的初始化后的长度。
    printf("-------------------------------------------------\n");
}

(三)打印当前顺序表,即循环遍历数组data[],就可以把当前数组的所有元素给输出,代码如下,由于我们声明的L是一个结构体类型的变量,可通过L.data[]和L.length获得当前的数组和长度,如果声明是结构体SqList类型的指针,则通过L->data[]和L->length获得当前的数组和长度:

//打印输出当前顺序表中的元素
void Print(SqList L)
{
    printf("当前表中的元素为:");
    for(int i=0;i<L.length;i++)
    {
        printf("%d ",L.data[i]);
    }
    printf("\n");
    printf("-------------------------------------------------\n");
}

(四)向当前顺序表中插入,将值e插入到顺序表的第i个位置上,这里的第i个位置是指从1开始。我们首先要判断i是否在有效的插入范围内,可以在第1个位置,或者是在第L->length个位置之后的第L->length个位置上插入,超过这个区间都是无效的。如果插入成功,则把第i个位置以及之后的元素全部都往后移动一位,我们知道第i个位置在数组中的下标为i-1,所以从i-1到L->length-1这些元素都要往后移动一位;

//向元素中插入元素
void InsertSq(SqList *L,int i,ElemType e)
{
    //首先要判断这个顺序表是否满了
    if(i>L->length+1||i<=0)
    {
        printf("i=%d插入位置不存在\n当前表的长度为:%d\n",i,L->length);
        printf("-------------------------------------------------\n");
    }
    else
    {
        for(int k=L->length-1;k>=i-1;k--)
        {
            L->data[k+1]=L->data[k];        //把它后面的都往后移动一位
        }
        L->data[i-1]=e;
        L->length++;//因为此时我们插入了一个元素,数组的长度要加1.
    }
}

(五)在当前顺序表中删除值为e的元素,我们也肯定要循环遍历这个数组,从数组的起始地址开始找值为e的元素,这时分为两种情况,要么找到了,把它后面的所有元素往前移动一位,同时数组的长度减少了1。要么找不到,打印输出我们当前这个数组中没有我们要删除的那个值。成功删除之后,我们要移动元素,此时我们需要把当前这个删除的元素所在的位置比如为i,此时i这个位置空出来了,它在数组中的下标为i-1,把它之后的元素,都往前移一位,我们只需要循环到L->length-2即可,看代码:

//在当前列表中删除值为x的元素
void DeleteSq(SqList *L,ElemType x)
{
    int i=0;
    while(i<L->length&&L->data[i]!=x){  //从头开始遍历,如果没找到,在符合条件下一直循环
        i++;
    }
    if(i>=L->length){//遍历完数组没有我们要删除的那个值
        printf("数组中没有你要删除的值为:%d的元素\n",x);
        printf("-------------------------------------------------\n");
    }
    else{
        printf("删除成功");
        for(int j=i;j<L->length-1;j++){    //把后一个值赋值到它的前一个元素所在的位置,所以到L->length-2即可。
            L->data[j]=L->data[j+1];
        }
        L->length--;
    }
}

(六)获取值为X的元素在数组中的下标,循环遍历数组,找到之后返回数组下标值,找不到就返回-1。

//获取值为X的元素在数组中的下标
int FindValue(SqList L,ElemType x)
{
    int i=0;
    while(i<L.length&&L.data[i]!=x)//循环遍历数组,如果不相等就循环找下一个
    {
        i++;
    }
    if(i>=L.length)      //遍历完数组还是没有找到
    {
        return -1;
    }
    return i;           //返回元素X所在的数组下标值
}

(七)获取第i个元素的值,先判断一下这个i是否在有效范围内,若在,则用*e来存储这个值,如果我们不同*e的话,这个值只能在这个函数中有效,无法返回主函数中。具体代码如下:

//获取第i个元素的值
void GetValue(SqList L,int i,ElemType *e)
{

    if(i<=0||i>L.length)
    {
        printf("您要查找的位置的有效范围为:1——%d\n",L.length);
        printf("您的输入为:%d,它不在数组的有效数字内\n",i);
    }
    else
    {
        (*e)=L.data[i-1];
        printf("您要查找的元素在第%d个位置,值为:e=%d\n",i,*e);
    }
    printf("-------------------------------------------------\n");
}

(八)获取顺序表的长度,代码如下:

//获取顺序表当前的长度
int GetLength(SqList L)
{
    return L.length;
}

(九)主函数代码:

int main()
{
    SqList s;//声明一个SqList类型的变量s,来标记这个顺序表
    ElemType e=0;
    InitSq(&s);            //初始化这个顺序表
    InsertSq(&s,1,23);     //插入五个元素
    InsertSq(&s,1,12);
    InsertSq(&s,1,5);
    InsertSq(&s,1,46);
    InsertSq(&s,3,89);
    Print(s);              //打印输出这五个元素
    int n,m;                 //定义变量,用来获取用户输入的要查找的元素的位置n,和值m
    printf("请输入你要查找的元素的位置:");
    scanf("%d",&n);
    GetValue(s,n,&e);     //获取第n个位置元素值
    printf("请输入你要查找的元素的值:");
    scanf("%d",&m);
    e=FindValue(s,m);     //获取值m在数组下标中的位置
    if(e>=0&&e<GetLength(s)){   //判断是否找到了那个元素。
        printf("您查找的元素%d,在数组中的下标为:%d\n",m,e);
        printf("-------------------------------------------------\n");
    }
    else{
        printf("您查找的元素%d不在数组中\n",m);
        printf("-------------------------------------------------\n");
    }
    int f;//f用于存储当前我们要删除的那个值
    printf("请输入你要删除的那个值:");
    scanf("%d",&f);
    DeleteSq(&s,f);
    Print(s);
    printf("当前数组的长度为:%d\n",s.length);
    printf("-------------------------------------------------\n");
    int r=0;
    printf("请输入你要插入的元素的值:");
    scanf("%d",&r);
    printf("向表中插入元素%d,插入之前顺序表的长度为:%d\n",r,s.length);
    InsertSq(&s,3,r);//在元素的第三个位置上插入888;
    Print(s);
    printf("插入之后顺序表的长度为:%d\n",s.length);
    return 0;
}

(十)测试结果如下:

总结:对于顺序表的实现,有很多种方式,这只是一种仅供大家参考,根据自己的习惯就行,哪个用着顺手,就用哪一种。

猜你喜欢

转载自blog.csdn.net/BaoITcore/article/details/121123351