线性表的顺序实现--C语言版

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>

#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
#define LISTINCREMENT 10 //线性表存储空间的分配增量
//操作算法中用到的预定义常量和类型
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
//Status 是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef int ElemType;

//线性表顺序结构的定义
typedef struct SqList
{
	ElemType* elem;  // 存储空间的基地址(首地址)
	int length;  //表中元素的个数(表长)
	int listsize; //表容量(以sizeof(ElemType)为单位)
}SqList;   //顺序表的类型定义


//顺序表的初始化
Status InitList_Sq(SqList* L)
{
	L->elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
	if (L->elem == NULL)
	{
		//printf("%s\n", strerror(errno));//防止内存分配失败的情况
		exit(OVERFLOW);
	}
	else
	{
		L->listsize = LIST_INIT_SIZE;   //初始存储容量
		L->length = 0;//初始化空表长度为0
	}
	return OK;
}

//顺序表的输入
void CreatList(SqList* L)
{
	printf("请输入元素个数:");
	scanf_s("%d", &L->length);
	printf("请输入要录入的数据:");
	for (int i = 0; i < L->length; i++)
	{
		scanf_s("%d", &L->elem[i]);
	}
}

//释放内存 销毁线性表L
void FreeList(SqList* L)
{
	if (L->elem != NULL)//这里要判断内存是否开辟成功,否则出现异常
	{
		free(L->elem);//谁申请谁释放
		L->elem = NULL;
	}
}

//清空线性表L
void ClearList(SqList* L)
{
	L->length = 0; //将线性表的长度置为0
}

//求线性表L的长度
int GetLength(SqList* L)//这里没有对线性表L进行修改,所以是否传递指针没有影响
{
	return L->length;
}

//判断线性表长度是否为空
int IsEmpty(SqList* L)//这里没有对线性表L进行修改,所以是否传递指针没有影响
{
	if (L->length == 0)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

//顺序表的取值(根据位置i获取相应位置数据元素的内容)
int GetElem(SqList L, int i, ElemType* e)
{
	if (i<1 || i>L.length)
	{
		return ERROR;  //判断i值是否合理,若不合理,返回ERROR
	}
	else
	{              //随机存取
		*e = L.elem[i - 1];//第i-1个单元存储着第i个元素
		return OK;
	}
}
//按值查找
//顺序表的查找
//在线性表L中查找与指定值e相同的数据元素的位置
int LocateELem(SqList L, ElemType e)
{
	int i = 0;
	for (i = 0; i < L.length; i++)//平均查找长度ASL(为确定记录在表中的位置,需要与给定值进行比较的关键字的个数的期望值叫做查找算法的平均查找长度)
	{
		if (L.elem[i] == e)
		{
			return i + 1;//假设有7个元素,那么它的平均查找长度就是1加到7再除以7等于4就是他的平均查找长度
		}
	}
	//假设每个记录的查找概率相等,则ASL=(n+1)/2

	return 0;


}

//顺序表的插入 第i个位置上插入一个新节点e  能插入的位置只有0到n+1个位置
//有三种情况,插入位置在最后,插入位置在中间,插入位置在最前面
//算法思想:
//1.判断插入位置i是否合法
//2.判断顺序表的存储空间是否已满,若已满返回ERROR
//3.从最后一个元素开始,将第n至第i为的元素依次向后移动一个位置,空出第i个位置
//4.将要插入的新元素e放入第i个位置 lenth+1
Status ListInsert(SqList* L, int i, ElemType e)  //第i个位置插入e
{
	int j = 0;
	if (i<1 || i>L->length + 1)//i值不合法
	{
		return ERROR;
	}
	if (L->length == L->listsize)//当前存储空间已满
	{
		return ERROR;
	}
	for (j = L->length - 1; j >= i - 1; j--)//元素个数减1就是下标所在位置
	{
		L->elem[j + 1] = L->elem[j]; //将前面一个元素的位置往后移动
	}
	L->elem[i - 1] = e;//将新元素e放入第i个位置
	L->length++;//表长增加1
	return OK;    //该算法的时间复杂度为O(n)
}//算法时间主要耗费在移动元素的操作上  平均移动次数=n/2  n为线性表中元素的个数

//顺序表元素的删除操作
//算法思想
//1.判断删除位置i是否合法(合法值为1<=i<=n)
//2.将欲删除的元素保留在e中
//3.将第i+1至第n为的元素依次向前移动一个位置
//4.表长减1,删除成功返回OK
Status ListDelete_Sq(SqList* L, int i)
{
	int j = 0;
	if (i<1 || i>L->length)//若i值不合法
	{
		return ERROR;
	}
	for (j = i; j <= L->length - 1; j++)
	{
		L->elem[j - 1] = L->elem[j];//将删除元素之后的元素前移
	}
	L->length--;//表长减1
	return OK;//平均移动次数=(n-1)/2
}
void menu()
{
	printf("1.初始化\n");
	printf("2.输入\n");
	printf("3.取值\n");
	printf("4.查找\n");
	printf("5.插入\n");
	printf("6.删除\n");
	printf("7.清空\n");
	printf("8.查看\n");
	printf("9.销毁\n");

}

int main()
{
	SqList L;
	menu();
	int menu = 0;
	int a = 0;
	int k = 0;
	while (!a)
	{
		scanf_s("%d", &menu);
		switch (menu)
		{
		case 1:
			k = InitList_Sq(&L);
			if (k == OK)
			{
				printf("初始化成功\n");
			}
			else
			{
				printf("初始化失败\n");
			}
			break;
		case 2:
		{
			CreatList(&L);
			break;
		}
		case 3:
		{
			int wh = 0;//接收函数的值						
			int w = 0;//查询的位置
			int e = 0;
			printf("请输入你要查询的位置:");
			scanf_s("%d", &w);
			//int GetElem(SqList L, int i, ElemType * e)
			wh = GetElem(L, w, &e);
			if (wh == ERROR)
			{
				printf("位置输入错误,请重新输入\n");
			}
			else
			{
				printf("你所查询的位置的值为:%d\n", e);
			}

			break;
		}
		case 4:
		{
			int i = 0;
			int e = 0;
			printf("请输入你要查找的值:\n");
			scanf_s("%d", &i);
			//int LocateELem(SqList L, ElemType e)
			e = LocateELem(L, i);
			if (e == 0)
			{
				printf("表中没有该元素\n");
			}
			else
			{
				printf("你所查询的值是表中第%d个元素\n", e);
			}
			break;
		}
		case 5:
		{
			int i = 0;
			int e = 0;
			int wh = 0;
			//ListInsert(SqList * L, int i, ElemType e)  //第i个位置插入e
			printf("请输入要插入的值:");
			scanf_s("%d", &e);
			printf("\n请输入要插入的位置:");
			scanf_s("%d", &i);
			wh = ListInsert(&L, i, e);
			if (wh == ERROR)
			{
				printf("i的位置不合法或存储空间已满\n");
			}
			else
			{
				printf("操作成功!\n");
			}
			break;
		}
		case 6:
		{
			int i = 0;
			int wh = 0;
			printf("请输入要删除的元素的位置:");
			scanf_s("%d", &i);
			wh = ListDelete_Sq(&L, i);
			if (wh == ERROR)
			{
				printf("输入的位置不合法");
			}
			else
			{
				printf("\n操作成功!");
			}
			break;
		}
		case 7:
		{
			ClearList(&L);
			printf("操作成功!\n");
			break;
		}
		case 8:
		{
			int i = 0;
			int a, b;
			a = GetLength(&L);
			b = IsEmpty(&L);
			if (b == 1)
			{
				printf("该表长度为空\n");
			}
			else
			{
				printf("\n该表长度为%d", a);
				printf("\n表中内容为:\n");
				for (i = 0; i < L.length; i++)
				{
					printf("%d ", L.elem[i]);

				}
			}
			break;
		}
		case 9:
		{
			FreeList(&L);
			printf("操作成功! 该线性表已销毁\n");
			return 0;
			break;
		}

		default:
		{
			printf("输入错误,请重新输入");
		}
		}
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值