线性表——顺序存储(C语言版,附带源代码)

时间:2021-12-06 00:27:14

 顺序表存储结构容易实现随机存取线性表的第i个数据元素的操作。

     但是在实现插入,删除的操作时需要移动大量的数据元素,所以它适用于数据相对稳定的线性表。

 /* c2-1.h 线性表的动态分配顺序存储结构 */
 #define LIST_INIT_SIZE 10 /* 线性表存储空间的初始分配量 */
 #define LIST_INCREMENT 2 /* 线性表存储空间的分配增量 */
 typedef struct
 {
   ElemType *elem; /* 存储空间基址 */
   int length; /* 当前长度 */
   int listsize; /* 当前分配的存储容量(以sizeof(ElemType)为单位) */
 }SqList;;


线性表——顺序存储(C语言版,附带源代码)

线性表——顺序存储(C语言版,附带源代码)

 

Status ListInsert(SqList *L,int i,ElemType e) /* 算法2.4 */
 { /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)+1 */
   /* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
   ElemType *newbase,*q,*p;
   if(i<1||i>(*L).length+1) /* i值不合法 */
     return ERROR;
   if((*L).length>=(*L).listsize) /* 当前存储空间已满,增加分配 */
   {
     newbase=(ElemType *)realloc((*L).elem,((*L).listsize+LIST_INCREMENT)*sizeof(ElemType));
     if(!newbase)
       exit(OVERFLOW); /* 存储分配失败 */
     (*L).elem=newbase; /* 新基址 */
     (*L).listsize+=LIST_INCREMENT; /* 增加存储容量 */
   }
   q=(*L).elem+i-1; /* q为插入位置 */
   for(p=(*L).elem+(*L).length-1;p>=q;--p) /* 插入位置及之后的元素右移 */
     *(p+1)=*p;
   *q=e; /* 插入e */
   ++(*L).length; /* 表长增1 */
   return OK;

}

线性表——顺序存储(C语言版,附带源代码)


<span style="font-size:18px;"><span style="font-size:18px;">#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

struct sqlist 
{
	int *elem; //存储空间基址
	int length;//当前长度
	int listsize;//当前分配的存储容量
};


void sqlist_init(struct sqlist *L,int len)  //建立一个空的的顺序表
{
	L->elem =(int *)malloc(sizeof(int) * len);//malloc函数的作用是分配字节空间(int占的字节数*存储容量),因为                                                  //要赋值给L->elem(int型指针),所以要通过(int *)来强制转换
	L->length =0;  //空表长度为0
	L->listsize =len; //存储容量为len 
}

void sqlist_input(struct sqlist *L)  //为顺序表输入数据
{
	int i,n;
	printf("          请输入要输入元素的个数:");
	scanf("%d",&n);
	printf("          请输入要输入的元素\n");
	for(i=0;i<n;i++)
	{
		scanf("%d",&(L->elem [i]));//例如:int e[10];这里的&(L->elem[i]) 和&(e[i])一个意思
		L->length ++;
	}
}

void sqlist_output(struct sqlist *L)  //输出顺序表中的数据
{
   int i;
   FILE *fp=fopen("sqlist.dat","w+");//新建一个文件“sqlist.dat”,“w+”为读写建立一个新的字符文件
   for(i=0;i<L->length ;i++)
   {
	   printf("%d\n",L->elem [i]);
       fprintf(fp,"%d\n",L->elem [i]);//将数据写入文件中
   }   
}


void output(struct sqlist *L)  //将数据写入文件
{
   int i;
   FILE *fp=fopen("sqlist.dat","w+");
   for(i=0;i<L->length ;i++)
   {
       fprintf(fp,"%d\n",L->elem [i]);
   }   
}


void sqlist_insert(struct sqlist *L, int i, int e)  //在顺序表插入数据
{
	int *j,*p;
	if(i<1||i>L->length +1)
	{
		printf("插入位置非法\n");
		exit(0);
	}
	j=&(L->elem [i-1]);  //j为插入位置地址
	for(p=&(L->elem [L->length -1]);p>=j;--p)  //从后向前(从右向左)循环
		*(p+1)=*p;  //插入位置及之后的元素右移
	*j=e;  //插入e
        ++L->length ; //在这里写成 L->length ++;也行
}

void sqlist_delete(struct sqlist *L, int i)  //在顺序表中删除数据
{
	int *j,*q,*p;
	if(L->length ==0)
	{
		printf("现行表为空,退出运行\n");
		exit(0);
	}
	if(i<1||i>L->length )
	{
		printf("删除位置非法\n");
		exit(0);
	}
	j=&(L->elem [i-1]);  //j为删除位置地址
	q=L->elem +L->length -1;//或者写成q=&(L->elem[L->length-1]);</span><span style="font-size:18px;">
	for(++j;j<=q;++j)   //这里必须写成++j
		*(j-1)=*j;  //删除位置及之后的元素左移
        --L->length ;
}

void sqlist_statistical(struct sqlist *L)  //统计顺序表中的奇偶数目
{
	int *p;
	int count_odd=0;
	int count_even=0;
	for(p=L->elem ;p<=L->elem +L->length -1;p++)
	{
		if(*p%2==0)
			count_even++;
		if(*p%2==1)
			count_odd++;
	}
	printf("          顺序表中的偶数个数为%d\n",count_even);
	printf("          顺序表中的奇数个数为%d\n",count_odd);
}

void sqlist_look(struct sqlist *L,int i)  //查询顺序表中的单独数据
{
	   printf("%d\n",L->elem [i-1]);  
}

void main_sqlist(struct sqlist *L)
{
	int i,e;
	int choose=0;
	printf("              以下是对顺序表的操作\n");
	printf("-------------------------------------------------------\n");
        printf("          1.              在顺序表插入数据\n");
        printf("          2.              在顺序表中删除数据\n");
	printf("          3.              输出顺序表中的数据\n");
	printf("          4.              查询顺表表中单独的数据\n");
	printf("          5.              统计顺序表中的奇偶数目\n");
	printf("-------------------------------------------------------\n");
    printf("              请选择你的操作:");
	scanf("%d",&choose);
	switch(choose)
	{
	case 1: {
		    printf("请输入要插入的位置:");
	            scanf("%d",&i);
	            printf("请输入要插入的元素:");
                    scanf("%d",&e);
	            sqlist_insert(L,i,e); //在顺序表插入数据
		}break;
	case 2: {
		     printf("请输入要删除元素的位置:");
	             scanf("%d",&i);
	             sqlist_delete(L,i);  //在顺序表中删除数据
		}break;
        case 3: sqlist_output(L);  //输出顺序表中的数据
	         break;
	case 4: {
		     printf("请输入要查询元素的位置:");
                     scanf("%d",&i);
	             sqlist_look(L,i);  //查询顺表表中单独的数据
		}break;
        case 5: sqlist_statistical(L);  //统计顺序表中的奇偶数目
		     break;
	} 
	printf("          是否继续执行操作(1.是 2.否):");
	scanf("%d",&choose);
        if(choose==1)
		main_sqlist(L);
	else
	{
		output(L);  //将数据写入文件
		exit(-1);
	}	
}


void main()
{	
    struct sqlist L;
    FILE *fp=fopen("sqlist.dat","w+");
    sqlist_init(&L,20);  //建立一个空的的顺序表
    sqlist_input(&L);  //为顺序表输入数据
    main_sqlist(&L);  
}</span></span>

注:图片来自 sjmp的博客