顺序表的12种基本操作

顺序表的12种基本操作

定义常量

/*一些经常用到的头文件,预定义常量等*/
//常用头文件
#include <stdio.h>
#include <malloc.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
//函数结果状态代码
#define TRUE	1
#define FALSE	0
#define OK		1
#define ERROR	0
#define INFEASIBLE	0
//新建函数类型,表示函数运行结果
typedef int Status;

结构体定义与函数声明

//顺序表结构体定义
#define LIST_INIT_SIZE 100  //线性表存储空间的初始分配量
#define LISTINCREMENT 10	//线性表存储空间的分配增量
typedef int ElemType;
typedef struct
{
	ElemType* elem;	//基地址
	int length;		//当前长度,即有效元素个数
	int listsize;	//当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;

//顺序表12种基本操作函数声明
Status InitList(SqList* L);
Status DestoryList(SqList* L);
Status ClearList(SqList* L);
Status ListEmpty(SqList L);
int ListLength(SqList L);
Status GetElem(SqList L, int i, ElemType* e);
int LocateElem(SqList L, ElemType e, Status(*compare)(ElemType, ElemType));
Status PriorElem(SqList L, ElemType cur_e, ElemType* pre_e);
Status NextElem(SqList L, ElemType cur_e, ElemType* next_e);
Status ListInsert(SqList* L, int i, ElemType e);
Status ListDelete(SqList* L, int i, ElemType *e);
Status ListTraverse(SqList L, Status (*visit)(ElemType*));
//两个辅助函数
Status compare(ElemType x, ElemType y);
Status visit(ElemType *);

函数定义

//顺序表的12个基本操作函数定义
Status InitList(SqList* L)
{
	L->elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));	//创建空表
	if (!L->elem)	exit(-1);	//判断是否创建成功
	L->length = 0; //初始长度为0
	L->listsize = LIST_INIT_SIZE;	//初始分配LIST_INIT_SIZE个sizeof(int)大小的容量
	return OK;
}

Status DestoryList(SqList* L)
{
	free(L->elem);	//释放主调函数中L中的elem指针指向的数组占用的空间
	L->elem = NULL;	//将elem指针变量本身置空
	L->length = 0;
	L->listsize = 0;
	return OK;
}

Status ClearList(SqList* L)
{
	L->length = 0;
	return OK;
}

Status ListEmpty(SqList L) 
{
	if (L.length == 0)	return TRUE;
	else				return FALSE;
}

int ListLength(SqList L)
{
	return L.length;
}

Status GetElem(SqList L, int i, ElemType* e)
{
	if (i<1 || i>L.length)	exit(ERROR); //若i不符合范围
	*e = *(L.elem + i - 1);
	return OK;
}

int LocateElem(SqList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
	int i = 1;	//当前位置
	ElemType* p = L.elem; //p扫描
	while (i <= L.length && !(*compare)(e, *p))
	{
		p++;
		i++;
	}
	//循环结束, 有两种情况
	if (i <= L.length)	return i;
	else return 0;
}

Status PriorElem(SqList L, ElemType cur_e, ElemType* pre_e)
{
	int i = 2;	//从第二个开始,因为第一个元素没有前驱元素
	ElemType* p = L.elem + 1;	//扫描指针也从第二个开始
	while (i <= L.length && !(*p == cur_e))
	{
		i++;
		p++;
	}

	if (i > L.length)
		return INFEASIBLE;
	else
	{
		*pre_e = *(--p);
		return OK;
	}
}

//PriorElem方法二
Status PriorElem(SqList L, ElemType cur_e, ElemType* pre_e)
{
	ElemType* p = L.elem;
	ElemType* q; 	//q指向p的后继
	while (p + 1)
	{
		q = p + 1;
		if (*q == cur_e)
		{
			*pre_e = *p;
			return OK;
		}
		p++;
	}
	return ERROR;
}

Status NextElem(SqList L, ElemType cur_e, ElemType* next_e)
{
	int i = 1;
	ElemType* p = L.elem;
	while (i <= L.length - 1 && !(*p == cur_e))	//当扫描到最后一个元素或者满足*p == cur_e时循环结束
	{
		i++;
		p++;
	}

	if (i > L.length - 1)
		return INFEASIBLE;
	else
	{
		*next_e = *(++p);
		return OK;
	}
}

//NextElem方法二
Status NextElem(SqList L, ElemType cur_e, ElemType *next_e)
{
	ELemType *p = L.elem;
    while(p+1)
    {
        if(*p == cur_e)
        {
            *next_e = *p;
            return OK;
        }
        p++;
    }
    
    return ERROR;
}

Status ListInsert(SqList* L, int i, ElemType e)
{
	if (i<1 || i>ListLength(*L) + 1) return ERROR;	//当i不符合范围时
	if (L->length >= L->listsize)	//当已分配的储存空间用完时
	{
		ElemType* newbase;	//新基地址
		newbase = (ElemType*)realloc(L->elem, (L->listsize + LISTINCREMENT) * sizeof(ElemType));
		if (NULL == newbase)	//判断是否创建成功
		{
			printf("空间分配失败!\n");
			exit(-1);
		}
		L->elem = newbase;	//使用新基地址
		L->listsize += LISTINCREMENT; 	//存储容量增大
	}

	//使原数组下标为i-1及之后的元素后移一位
	ElemType* q, * p;
	q = L->elem+i-1;	//q指向第i(下标i-1)个元素
	p = L->elem+L->length-1;	//p指向最后一个元素
	for (; p >= q; p--)
		*(p + 1) = *p;	//后移
	*q = e;	//插入
	L->length++;	//表长增加

	return OK;
}

Status ListDelete(SqList* L, int i, ElemType *e)
{
	if (i<1 || i>L->length) return ERROR;	//当i超出范围时
	ElemType *q, *p;	//q删除位置,即下标为i-1的指针; p线性表最后一位元素的指针
	q = L->elem+i-1;
	p = L->elem+L->length-1;
	*e = *q;	//e存放删除的值
	for (q++; q <= p; q++)
		* (q - 1) = *q;	//前移
	L->length--;	//表长减1

	return OK;
}

Status ListTraverse(SqList L, Status (*visit)(ElemType*))
{
	ElemType* p = L.elem;	//p扫描指针,从第一个元素开始
	int i;
	for(i=1; i<=ListLength(L); i++)
		visit(p++); 	//把指针传递给visit,则可以通过visit修改值
	printf("\n");
	return OK;
}

测试

//顺序表的12个基本操作检测
#include "SqList.cpp"

int main()
{
	SqList L;
	if (InitList(&L))	printf("创建成功!\n");
	else				printf("创建失败!\n");
	//求表长
	printf("表长为:%d\n", ListLength(L));
	//判空
	if (ListEmpty(L))	printf("表空!\n");
	else				printf("非空!\n");
	//插入元素
	ElemType i;
	for (i = 1; i <= 20; i++)
	{
		if (ListInsert(&L, 1, i))	printf("头插入成功:%d\n", i);
		else					printf("头插入失败!\n");
	}
	//判表空
	if (ListEmpty(L))	printf("空!\n");
	else				printf("非空!\n");
	//表长
	printf("表长为:%d\n", ListLength(L));
	//遍历
	ListTraverse(L, visit);
	//取元素
	if (GetElem(L, 2, &i))	printf("取第2个元素:%d\n", i);
	else					printf("获取失败!\n");
	//定位元素
	int n = LocateElem(L, 2, compare);
	if (i != 0)	printf("与2相关的元素是第%d个\n", n);
	else		printf("定位失败!\n");
	n = LocateElem(L, 9, compare);
	if (n != 0)	printf("与9相关的元素是第%d个\n", n);
	else		printf("定位失败!\n");
	//前后继元素
	if (PriorElem(L, 2, &i))	printf("2的前元素:%d\n", i);
	else						printf("获取失败!\n");
	if (PriorElem(L, 8, &i))	printf("8的前元素:%d\n", i);
	else						printf("获取失败!\n");
	if (NextElem(L, 2, &i))		printf("2的后元素:%d\n", i);
	else						printf("获取失败!\n");
	if (NextElem(L, 1, &i))		printf("1的后元素:%d\n", i);
	else						printf("获取失败!\n");
	//删除
	if (ListDelete(&L, 1, &i))	printf("删除第%d个元素:%d\n", 1, i);
	else						printf("删除失败!\n");
	if (ListDelete(&L, 3, &i))	printf("删除第%d个元素:%d\n", 3, i);
	else						printf("删除失败!\n");
	//表长
	printf("表长为:%d\n", ListLength(L));
	//遍历
	ListTraverse(L, visit);
	//清空
	if (ClearList(&L))	printf("清空成功!\n");
	else				printf("清空失败!\n");
	//判表空
	if (ListEmpty(L))	printf("空!\n");
	else				printf("非空!\n");
	//表长
	printf("表长为:%d\n", ListLength(L));
	//遍历
	ListTraverse(L, visit);
	//销毁链表
	if (DestoryList(&L))	printf("销毁成功!\n");
	else				printf("销毁失败!\n");

	return 0;
}

Status compare(ElemType x, ElemType y)
{
	if (x == y)
		return OK;
	else
		return ERROR;
}

Status visit(ElemType *e)
{
	printf("%d ", *e);
	return OK;
}

运行结果

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值