线性表——动态顺序表

顺序表的优点:

支持随机访问

顺序表的缺点:

1、插入或删除时移动数据存在消耗;

2、空间不足时需要扩容,扩容存在消耗;

3、为了防止频繁扩容,扩容时通常扩容到之前的几倍,难免存在空间浪费

C语言实现动态顺序表

文件一  SeqList.h 

1、结构体的定义

2、各类接口函数的声明

//文件一  SeqList.h 


#pragma once
#include<stdio.h>


typedef int SLDataType;//统一管理存入数据的类型 
typedef struct SeqList
{
	SLDataType *a;  //开辟的空间的首地址 
	int size;       //当前存入数据的数目 
	int capacity;   //当前空间的总容量 
}SL;


void SeqListInit(SL* p);                                 //顺序表的初始化 

void SeqListCheckCapacity(SL* p);                        //检查空间的总容量  

void SeqListPushBack(SL* p,SLDataType x);                //表尾插入 
void SeqListPopBack(SL* p);                              //表尾删除 
void SeqListPushFront(SL* p,SLDataType x);               //表头插入 
void SeqListPopFront(SL* p);                             //表头删除 

void SeqListInsert(SL* p,int pos,SLDataType x);          //选择插入 
void SeqListErase(SL* p,int pos);                        //选择删除 

int  SeqListFind(SL* p,SLDataType x);                    //查找数据

void SeqListPrint(SL* p);                                //打印数据 

void SeqListDestroy(SL* p);                              //释放空间 

文件二  SeqList.c

各类接口函数的实现

//文件二  SeqList.c 


#include<stdio.h>
#include<assert.h>
#include"SeqList.h"



void SeqListInit(SL* p)                     //表的初始化                                         
{
	p->a=NULL;
	p->size=p->capacity=0;
}

void SeqListCheckCapacity(SL* p)      //检查空间的总容量                                          
{
	if(p->size==p->capacity)
	 {
	 	//使用realloc扩容,realloc的第二个参数是内存空间的字节数 
	 	//首次扩容到4,为了防止频繁扩容,所以之后都是扩容到之前的两倍 
	 	int new_capacity=p->capacity==0?4:p->capacity*2;
	 	SLDataType *tem=(SLDataType *)realloc(p->a,new_capacity*sizeof(SLDataType));
	 	
	 	if(tem==NULL)//扩容失败 
	 	  {
	 	  	printf("Realloc fail!\n");
	 	  	exit(-1);//非正常退出当前运行的程序 
		  }
		
	    p->a=tem;
	    p->capacity=new_capacity;
	 }
}

void SeqListPushBack(SL* p,SLDataType x)      //表尾插入                                               
{
	SeqListCheckCapacity(p);//添加数据前检查空间的总容量 
	
	p->a[p->size]=x;//size比当前存储有数据的空间的最大下标值大1 
	p->size++;
}

void SeqListPopBack(SL* p)                    //表尾删除                                                       
{
	assert(p->size>0);
	p->size--;
	//如果以后有添加数据的情况,之前的表尾数据会被覆盖 
	//之前的表尾数据无法被函数SeqListPrint(打印数据)访问
}

void SeqListPushFront(SL* p,SLDataType x)     //表头插入                                             
{
	SeqListCheckCapacity(p);//添加数据前检查空间的总容量 
	 
    int end=p->size-1;
    while(end>=0)
      {
      	p->a[end+1]=p->a[end];
      	end--;
	  }
    //从下标为p->size-1处开始,从后往前把每一个数据都往后移动一个单位 
    
    p->a[0]=x;
    p->size++;
}

void SeqListPopFront(SL* p)                  //表头删除                                                        
{
	assert(p->size>0);
	
	int begin=1;
	while(begin<p->size)
	  {
	  	 p->a[begin-1]=p->a[begin];
	  	 begin++;
	  }
	//从下标为1处开始,从前往后把每一个数据都往前移动一个单位,表头数据被覆盖  
	  
    p->size--;
}

void SeqListInsert(SL* p,int pos,SLDataType x)//选择插入                                           
{
	assert(pos>=0&&pos<=p->size);
	SeqListCheckCapacity(p);//添加数据前检查空间的总容量 
	
	int end=p->size-1;
	while(end>=pos)
	  {
	  	p->a[end+1]=p->a[end];
	  	end--;
	  }
	  
    p->a[pos]=x;
    p->size++;
}

void SeqListErase(SL* p,int pos)             //选择删除                                                       
{
	assert(pos>=0&&pos<p->size);
	
	int begin=pos+1;
	while(begin<p->size)
	  {
	  	 p->a[begin-1]=p->a[begin];
	  	 begin++;
	  }
	  
    p->size--;
} 

int SeqListFind(SL* p,SLDataType x)          //查找数据                                                 
{
	int i;
	for(i=0;i<p->size;i++)
	  if(p->a[i]==x)
	    return i;//若有多个x,返回的是最小的下标 
	    
    return -1;
}

void SeqListPrint(SL* p)                     //打印数据                                                            
{
	int i;
	for(i=0;i<p->size;i++)
	  printf("%d ",p->a[i]);
    printf("\n");
}
 
void SeqListDestroy(SL* p)                   //释放空间                                                       
{
	free(p->a);
	p->a=NULL;
	p->size=p->capacity=0;	
}

文件三  SeqListTest.c

测试用例

//文件三  SeqListTest.c


#include<stdio.h>
#include"SeqList.h"


void SeqListTest()
{
	SL sl;
	
	//顺序表的初始化
	SeqListInit(&sl);
	
	SeqListPushBack(&sl,0);
	SeqListPushBack(&sl,7);
	SeqListPushBack(&sl,1);
	SeqListPushBack(&sl,9);
	SeqListPushBack(&sl,0);
	SeqListPushBack(&sl,0);
	printf("测试1(表尾插入):\n");
	SeqListPrint(&sl);
	printf("-------------------------\n");
	
	SeqListPopBack(&sl);
	SeqListPopBack(&sl);
	printf("测试2(表尾删除):\n");
	SeqListPrint(&sl);
	printf("-------------------------\n");
	
	SeqListPushFront(&sl,2);
	SeqListPushFront(&sl,2);
	SeqListPushFront(&sl,0);
	SeqListPushFront(&sl,2);
	SeqListPushFront(&sl,0);
	SeqListPushFront(&sl,0);
	printf("测试3(表头插入):\n");
	SeqListPrint(&sl);
	printf("-------------------------\n");
	
	SeqListPopFront(&sl);
	SeqListPopFront(&sl);
	printf("测试4(表头删除):\n");
	SeqListPrint(&sl);
	printf("-------------------------\n");
	
	SeqListInsert(&sl,5,0);
	SeqListInsert(&sl,9,0);
	printf("测试5(选择插入):\n");
	SeqListPrint(&sl);
	printf("-------------------------\n");
	
	SeqListErase(&sl,9);
	SeqListErase(&sl,5);
	printf("测试6(选择删除):\n");
	SeqListPrint(&sl);
	printf("-------------------------\n");
	
	printf("测试7(查找数据):\n");
	printf("2的最小下标是:%d\n",SeqListFind(&sl,2));
	printf("7的最小下标是:%d\n",SeqListFind(&sl,7));
	printf("9的最小下标是:%d\n",SeqListFind(&sl,9));
	printf("-------------------------\n");
	
	printf("测试8(输出最终结果):\n");
	SeqListPrint(&sl);
	
	//可以在此处添加更多测试
	
	//释放空间
	SeqListDestroy(&sl);
}


int main()
{
	SeqListTest();

	return 0;
}

测试用例输出效果图

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值