C语言 数据结构顺序表的基本操作(附输入样例和讲解)

我的代码参照了严蔚敏、吴伟民编写的数据结构(C语言版)
所有代码采用C语言编写。讲解请查看注释。
*另注:书中很多函数采用了引用传值,如InitList(Sqlist &L)。但C语言并不支持引用传值,因此统一改为地址传值,即InitList(Sqlist *L)。

头文件及宏定义

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
//线性表动态分配存储结构
#define LIST_INIT_SIZE 100//初始分配量 
#define LISTINCREMENT 10//分配增量 
#define OK 1
#define Fail 0 
#define False 0
#define True 1

typedef定义数据类型和结构体

typedef int ElemType;
typedef int Status;

typedef struct{
	ElemType* elem;
	int length;//长度 
	int listsize;//存储容量 //长度<=存储容量 
}Sqlist;

InitList(创建)

Status InitList_Sq(Sqlist* L){//创建 
//地址方式调用 ,获得传入参数(地址)对应的对象 
L->elem=(ElemType*)malloc(LIST_INIT_SIZE* sizeof(ElemType));//分配内存空间 ,malloc的返回值是一个指针,指向一段可用内存的起始地址
if(!L->elem)exit(OVERFLOW);
L->length=0;
L->listsize=LIST_INIT_SIZE;
return OK;
}

DestroyList(销毁)

Status DestroyList_Sq(Sqlist* L){//销毁 
	L->length=0;
	L->listsize=0;
	free(L->elem);
	return OK;
} 

ClearList(清空)

Status ClearList_Sq(Sqlist* L){//清空 
	L->length=0;
	return OK; 
} 

ListEmpty(判断表是否为空)

Status ListEmpty_Sq(Sqlist L){//判断顺序表是否为空 
	if(L.length==0)
	return True;
	else
	return False; 
}

ListLength(获得数据元素的个数)

Status ListLength_Sq(Sqlist L){//返回数据元素个数 
	return L.length; 
}

GetElem(获得第某个数据元素)

Status GetElem_Sq(Sqlist L,int i,ElemType* e){//返回第i个元素的值,将其存储在e中 

	if (i>=1&&i<=L.length){
	* e=L.elem[i-1];
	return OK;
	} 
}

Locate( 匹配数据元素)

需要先实现compare()方法。

Status compare(int i,int j){//在Locate_Sq()方法中用到 
	if(i==j)
	return 1;
	else
	return 0;
} 


Status Locate_Sq(Sqlist L,ElemType e,int compare()){//返回顺序表中与参数e相等的数据元素的次序 
	int i=0;
	int flag=0;
	for(i=0;i<L.length;i++){
		flag=compare(L.elem[i],e);//调用compare函数依次比较参数e和L中的数据元素 ,结果保存在flag中 
		if(flag==1){
			return i+1;//若找到相同的(flag=1),返回该数据元素的次序 (L.elem[i]中的i从0开始,因此加1) 
		}
	}
	return Fail;
} 

PriorElem(获得前驱数据元素)

Status PriorElem_Sq(Sqlist L,ElemType cur_e,ElemType* pre_e){//找前驱,并将pre_e修改为前驱,需要用到compare函数 
	int i=0;
	i=Locate_Sq(L,cur_e,compare);
	if(i>1){//若cur_e是表中元素(不是0),且不是第一个 (1)
	*pre_e=L.elem[i-2];//i是cur_e的次序,前驱的次序应-1,前驱的L.elem[j]应再-1 
	}
}

NextElem(获得后继数据元素)

Status NextElem_Sq(Sqlist L,ElemType cur_e,ElemType* next_e){//找后继,并将pre_e修改为前驱,需要用到compare函数 
	int i=0;
	i=Locate_Sq(L,cur_e,compare);
	if(i>0&&i<L.length){//若cur_e是表中元素(不是0),且不是最后一个 (L.length)
	*next_e=L.elem[i];//i是cur_e的次序,后继的次序就是L.elem[i] 
	}
}

ListInsert(插入数据元素)

Status ListInsert_Sq(Sqlist* L,int i,ElemType e){//在第i个位置之前插入新的数据元素e 
	if(i>=1&&i<=L->listsize){
	  L->length++;
	  int j=L->length;
	  for(j;j>i;j--){
		  L->elem[j-1]=L->elem[j-2];
	  } 
	  L->elem[i]=e;
	} 
	return OK;
}

ListDelete(删除数据元素)

Status ListDelete_Sq(Sqlist* L,int i,ElemType* e){//删除第i个位置的元素,将其值保存在e中 
	if(i>=1&&i<=L->listsize){
	  *e=L->elem[i-1];//第i个位置的元素对应的是elem[i-1],改变e的值使其等于elem[i-1]
	  
	  for(i;i<L->length;i++){
		  L->elem[i-1]=L->elem[i];
	  } 
	} 
	L->length--;
	return OK;
	
}

ListTraverse(遍历所有数据元素)

需要先实现visit()函数。

Status visit(Sqlist L){//访问元素,在ListTraverse()中用到 
	int i=0;
	for(i;i<L.length;i++){
	printf("%d\n",L.elem[i]);
	}
	return i;//返回遍历的元素个数 
}


Status ListTraverse(Sqlist L,int visit()){
	if(visit(L)==L.length){
		return OK;
	}
}

输入样例

很多函数被我注释掉了,需要使用的话自行取消注释。

int main(void){
	Sqlist L;
	InitList_Sq(&L);//创建表,传入表对应的地址
	L.elem[0]=1;//第一个元素 
	L.elem[1]=3;//第二个元素
	L.elem[2]=5;//第三个元素
	L.elem[3]=7;//第四个元素
	L.length=4;//共四个元素 
	
	//int elem1=0;
	//GetElem_Sq(L,2,&elem1);//获得第二个元素的值(3),存储在elem1中 
	//Locate_Sq(L,5,compare);//在顺序表中查找值为5的数据元素,若找到则返回次序 
	//PriorElem_Sq(L,L.elem[2],&elem1);//将elem[2]的前驱存储在elem1中
	//NextElem_Sq(L,L.elem[2],&elem1);//将elem[2]的后继存储在elem1中
	//ListInsert_Sq(&L,2,-1); //将值为-1的数据元素插入到第二个元素后面 
	//ListDelete_Sq(&L,2,&elem1); //删除第二个元素(L.elem[1]) 
	
	ListTraverse(L,visit);//遍历所有元素并输出,成功则返回OK 
	DestroyList_Sq(&L);//销毁表 
}

输出结果

输出结果

  • 3
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值