数据结构——线性表的顺序存储(优缺点及代码实现:C语言)

顺序存储

逻辑位置和内存中的物理位置相同,除第一个外都有且仅有一个直接前驱,除最后一一个元素外有且仅有一个直接后继。

*优点:

  1. 存储密度大,
  2. 存储空间利用率高,
  3. 可以实现随机存取,即直接通过地址访问元素

缺点:

  1. 插入和删除操作需要在物理上移动大量元素,这可能会导致效率低下,
  2. 需要预先分配连续的存储空间,这可能导致存储空间的浪费

综上:这种结构适合于频繁查找和访问元素的场景

代码实现

定义顺序表

#define MaxSize 100
typedef int DataType;                 //将DataType 设为int型
typedef   struct
{
  DataType data[MaxSize ];            // int data[100]
  int length;                          //表示当前长度
}SeqList;                     //结构体的别名,引用Seqlist=引用上述结构体

初始化

void InitSeqList(SeqList *L)
{
  L->length=0;
}

求表长

int GetLength(SeqList *L)
{
   return L->length;
}

按位查找

时间复杂度 O(1)

int GetElem(SeqList  *L, int i, DataType *x)
{  /*获取顺序表中第i位中元素函数*/
   if (i<1 || i>L->Length)
        return  0;
   else
   { 
	  *x = L->data[i-1];  //返回元素值
      return  1;
   }
}

按值查找

时间复杂度O(n)
ASL(平均查找长度): (n+1)/2

int Locate(SeqList *L,DataType x)
{
	int j=0;
	while(j<L->length && L->data[j]!=x)
		j++;
	if(j>=L->length)
		return 0;
	else
		return j+1;   /*返回的是元素位置*/
}

插入

  1. 判表满
  2. 判插入位置是否规范
  3. 后续元素循环后移
  4. 插入元素
  5. 表长+1

时间复杂度O(n)
ASL(平均查找长度): n/2

int InsElem(SeqList *L,int i,DataType x) /*插入位置i 插入元素x*/
{
	int j;
	if(L->length >= MaxSize)  //判表满
	{
		printf("顺序表已满");
		return -1;
	}
	if(i<1 || i > L->length+1)
	{
		printf("插入位置错");
		return 0;
	}
	for (j=L->Length-1; j>=i-1; j--)     /*结点移动*/ 
        L->data[j+1]=L->data[j];
    L->data[i-1]=x;                      /*新元素插入*/
    L->Length++;                         /*顺序表长度增1 */
    return 1;                           /*插入成功,返回*/
}

删除

  1. 判表空
  2. 判删除位置
  3. 后续元素前移
  4. 表长-1

时间复杂度: O(n)
ASL: (n-1)/2

int DelElem (SeqList *L, int i,  DataType *x)  
{   /*在顺序表L中删除第i位元素函数*/
	int  j;
    if (L->Length==0)
    {  printf ("顺序表为空!");
       return 0;                 /*表空,不能删除*/
    }
    if (i<1 || i>L->Length)           /*检查是否空表及删除位置的合法性*/
    {  printf ("不存在第i个元素");
       return 0;
    }
    *x= L->data[i-1];                /*用指针变量*x返回删除的元素值*/
    for(j=i;j<L->Length;j++)         
       L->data[j-1]=L->data[j];		  /*结点依次前移*/
    L->Length--;                     /*顺序表长度减1*/
    return 1;                        /*删除成功,返回*/
}

完整示例(C语言实现):

/*顺序表的各种操作程序*/
#include <stdio.h>
#include <stdlib.h> // 包含stdlib.h以使用malloc

#define  MAXLEN  100           /*定义常量MAXLEN为100表示存储空间总量*/
typedef  int  DataType;          /*定义ElemType为int类型*/ 
typedef  struct                  /*顺序表存储类型*/
{  /* DataType   data[MAXLEN];     存放线性表的数组*/
	DataType  *data;  
    int  Length;                 /*Length是顺序表的长度*/
}SeqList;

void  InitList( SeqList  *L )
{   /*初始化顺序表L函数*/ 
 	L->Length=0;                     /*初始化顺序表为空*/
}

void CreateList(SeqList *L,int n)
{  /*建立顺序表并输入多个元素函数*/
   int i;
   L->data = (DataType *)malloc(sizeof(DataType) * n);
   if(!L->data)
	   puts("error");
   printf("请输入%d个整数:",n);

   for(i=0;i<n;i++)
       scanf("%d",&L->data[i]);
   L->Length=i;                       /*设线性表的长度为i*/
}

int GetElem(SeqList  *L, int i, DataType *x)
{  /*获取顺序表中第i位中元素函数*/
   if (i<1 || i>L->Length)
        return  0;
   else
   { 
	  *x = L->data[i-1];
      return  1;
   }
}

int Locate(SeqList *L, DataType x)
{   /*在顺序表L中定位元素x函数*/
	int i=0;
    while(i<L-> Length && L->data[i]!= x)
        i++;
    if (i>=L->Length) 
       return 0;
    else
		return i+1;                     /*返回的是元素位置*/
}

int  InsElem(SeqList *L, int i, DataType x)
{   /*在顺序表L中在第i位中插入新元素x函数*/
	int j;
    if (L->Length>=MAXLEN)
    {   printf ("顺序表已满!"); 
        return -1;                      /*表满,不能插入*/
    }
    if (i<1 || i>L->Length+1)             /*检查给定的插入位置的正确性*/
    {   printf("插入位置出错!");
        return 0; 
    }
    if (i == L->Length+1)
    {   L->data[i-1]=x;
        L->Length++;
        return  1;             /*插入的位置为表尾,则不需移动直接插入即可*/ 
    }
    for (j=L->Length-1; j>=i-1; j--)     /*结点移动*/ 
        L->data[j+1]=L->data[j];
    L->data[i-1]=x;                      /*新元素插入*/
    L->Length++;                         /*顺序表长度增1 */
    return 1;                           /*插入成功,返回*/
}

int DelElem (SeqList *L, int i,  DataType *x)  
{   /*在顺序表L中删除第i位元素函数*/
	int  j;
    if (L->Length==0)
    {  printf ("顺序表为空!");
       return 0;                 /*表空,不能删除*/
    }
    if (i<1 || i>L->Length)           /*检查是否空表及删除位置的合法性*/
    {  printf ("不存在第i个元素");
       return 0;
    }
    *x= L->data[i-1];                /*用指针变量*x返回删除的元素值*/
    for(j=i;j<L->Length;j++)         /*结点移动*/
       L->data[j-1]=L->data[j];
    L->Length--;                     /*顺序表长度减1*/
    return 1;                        /*删除成功,返回*/
}

void DispList(SeqList *L)
{   /*显示输出顺序表L的每个元素函数*/
	int i;
    for(i=0;i< L->Length;i++)
       printf("%5d ", L->data[i]);
}

void  Menu()                                    
{   /*显示菜单子函数*/
	printf("\n                  顺序表的各种操作");
    printf("\n==================================================");  
    printf("\n|              1——建立顺序表                   |");
    printf("\n|              2——插入元素                     |");
    printf("\n|              3——删除元素                     |");
    printf("\n|              4——按位置查找元素               |");
    printf("\n|              5——按元素值查找其在表中位置     |");
    printf("\n|              6——求顺序表的长度               |");
    printf("\n|              0——返回                         |");
    printf("\n=================================================="); 
    printf("\n请输入菜单号(0-6):"); 	
}

main()
{
   SeqList L;
   DataType x;
   int n,i,loc;
   char  ch1,ch2,a;
   ch1='y';
   while(ch1=='y'||ch1=='Y') 
   {  Menu();
   	  scanf("%c",&ch2);
   	  getchar();
   	  switch(ch2)
   	  {
   	  	 case  '1':   	  	 
             InitList( &L );
             printf("请输入建立线性表的个数:");
             scanf("%d",&n);
             CreateList(&L,n);
             printf("建立的线性表为:");
             DispList(&L);
             break;
         case  '2':
             printf("请输入要插入的位置:");
             scanf("%d",&i);
             printf("请输入要插入的元素值:");
             scanf("%d",&x);
             if(InsElem(&L,i,x))
             {
                printf("已成功在第%d的位置上插入%d,插入后的线性表为:\n",i,x);
                DispList(&L);
             }
             else
                printf("输入插入的参数错误!");
             break;
         case  '3':
             printf("请输入要删除元素的位置:");
             scanf("%d",&i);
             if(DelElem (&L, i,  &x))
             {
                printf("已成功在第%d的位置上删除%d,删除后的线性表为:\n",i,x);
                DispList(&L);
             }
             else
                printf("\n输入删除的参数错误!");
             break;
         case  '4':
             printf("请输入要查看表中元素位置(从1开始):");
             scanf("%d",&i);
             if(GetElem(&L, i, &x))
                printf("当前线性表第%d个元素的值为:%d",i,x);
             else
                printf("输入的位置错误!");
             break;
         case  '5':
             printf("请输入要查找的元素值为:");
             scanf("%d",&x);
             loc=Locate(&L, x);
             if(loc)
                printf("查找元素值为%d的位置为:%d",x,loc);
             else
                printf("该表中无此元素!");
             break;
         case  '6':
             printf("当前线性表的长度为:%d",L.Length);
             break;
         case  '0':
             ch1='n';break;
         default:
             printf("输入有误,请输入0-4进行选择!");
   	  }
   	  if(ch2!='0')
   	  {   printf("\n按回车键继续,按任意键返回主菜单!\n");
   	  	  a=getchar();
   	  	  if(a!='\xA')
   	  	  {
   	  	  	 getchar();ch1='n';
   	  	  }
   	  }
   }
}

结语

敬请各位大佬批评指正 日后也会持续更新数据结构相关内容,互相学习😊😊
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值