数据结构 线性表的基础操作 C/C++代码实现 #1

线性表的基础操作

1.创建线性表

2.销毁线性表

3.清空线性表

4.检查线性表是否为空

5.返回线性表的数据元素个数

6.返回线性表中指定位置的元素的值

7.找到符合条件的元素,返回其位置

8.返回线性表中指定元素的前一个元素的位置

9.返回线性表中指定元素的后一个元素的位置

10.在线性表指定位置插入一个元素

11.删除线性表中指定位置的元素

12.遍历线性表

线性表的两种存储结构

1.顺序存储结构

2.链式存储结构

线性表的顺序存储结构C语言实现

首先是结构体:

typedef int elemtype;

typedef struct List1
{
	elemtype* data;
	int lenth;
	int listsize;
}List1,*Plist;

1.创建线性表

//lenth表示线性表最大的存储空间
int InitList1(Plist& list, int lenth)
{
	list = (Plist)malloc(sizeof(List1));
	if (list == NULL )	return 1;
	//如果空间申请失败返回1(当然,基本上不会出现问题)
	list->data = NULL;
	list->data = (elemtype*)malloc(sizeof(elemtype) * lenth);
	if ( list->data == NULL)	return 1;
	//如果空间申请失败返回1(同理)
	list->lenth = 0;
	list->listsize = lenth;
	return 0;
	//正常结束返回0
}

2.销毁线性表

int DestroyList1(Plist& list)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;//如果线性表本身就是不存在返回1
	}
	if((list->data)!=NULL)
		free(list->data);
	free(list);
	list = NULL;
	return 0;
}

3.清空线性表

int ClearList1(Plist& list)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	list->lenth = 0;
	return 0;
}

4.检查线性表是否为空

int List1Empty(Plist& list)
{
	if (list == NULL)	
	{
		printf_s("线性表不存在\n");
		return -1;
	}
	if (list->lenth == 0)	return 1;//线性表为空返回1
	else return 0;//不为空返回0
}

5.返回线性表数据元素的个数

int List1Length(Plist& list)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return -1;
	}
	return list->lenth;
}

6.返回线性表中指定位置的元素的值

//找到指定位置,并将元素的值放入e中
int GetElemList1(Plist& list,int i,elemtype &e)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (i >= list->lenth)
	{
		printf_s("该位置没有元素\n");
		return 2;
	}
	e = list->data[i];
	return 0;
}

7.找到符合条件的元素,返回其位置

//自定义比较函数,如果啊a<b返回1
bool compare(elemtype a, elemtype b)
{
	return a < b;
}

//该处知识点涉及——函数指针,很少使用,但是也需要了解
bool (*p)(elemtype a, elemtype b) = compare;

//查找符合条件的元素,并返回
int LocateElemList1(Plist& list, elemtype e, bool (*compare)(elemtype a, elemtype b))
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return -1;
	}
	for (int i = 0; i <= list->lenth; i++)
	{
		if (compare(e, list->data[i]))
		{
			return i;
			//compare 表示如果a<b则为1;结果返回的就是线性表中第一个比e小的数字的位置
		}
	}
	return -2;//没有比e小的数字则返回-2
}

函数指针的用法我会在这篇文章的最后简单调用一下给你们看。


对于顺序结构的线性表来说,查找元素的前驱和后继意义不大,但我还是写上了,不过没有多少注释了,这部分看不看都可以。

8.返回线性表中指定元素的前一个元素的位置

int PriorElem(Plist& list, elemtype cur_e, elemtype& pre_e)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (list->lenth <= 1)
	{
		if (list->lenth == 0)
		{
			printf_s("List is empty\n");
			return 2;
		}
		else if (list->lenth == 1)
		{
			printf_s("Can't find the precursor, because there's only one\n");
			return 3;
		}
	}
	for (int i = 0; i < list->lenth; i++)
	{
		
		if (cur_e == list->data[i])
		{
			if (i != 0)
			{
				pre_e = i - 1;
				return 0;
			}
			else
			{
				printf_s("Can't find the precursor, because it's the first\n");
				return 4;
			}
		}
	}
	printf_s("Can't find the precursor because there's no such element\n");
	return 5;
}

9.返回线性表中指定元素的后一个元素的位置

int NextElem(Plist& list, elemtype cur_e, elemtype& next_e)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (list->lenth <= 1)
	{
		if (list->lenth == 0)
		{
			printf_s("List is empty\n");
			return 2;
		}
		else if (list->lenth == 1)
		{
			printf_s("Can't find the successor, because there's only one\n");
			return 3;
		}
	}
	for (int i = 0; i < list->lenth; i++)
	{

		if (cur_e == list->data[i])
		{
			if (i != list->lenth-1)
			{
				next_e = i + 1;
				return 0;
			}
			else
			{
				printf_s("Can't find the successor, because it's the last one\n");
				return 4;
			}
		}
	}
	printf_s("Can't find the successor because there's no such element\n");
	return 5;
}

10.在线性表指定位置插入一个元素

//指定位置之前插入元素
int List1Insert(Plist& list, int numth, elemtype e)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (list->lenth == list->listsize)
	{
		printf_s("线性表已满,无法操作。\n");
		return 2;
	}
	if (numth > list->lenth)
	{
		printf_s("该位置无效,无法操作\n");
		return 3;
	}
	for (int i = list->lenth; i > numth; i--)
	{
		list->data[i] = list->data[i - 1];
	}
	list->data[numth] = e;
	list->lenth++;
	return 0;
}

11.删除线性表中指定位置的元素

int List1Delete(Plist& list, int numth, elemtype &e)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (list->lenth == 0)
	{
		printf_s("线性表已满\n");
		return 2;
	}
	if (numth >= list->lenth)
	{
		printf_s("该位置没有元素\n");
		return 3;
	}
	e = list->data[numth];
	for (int i = numth; i < list->lenth-1; i++)
	{
		list->data[i] = list->data[i + 1];
	}
	list->lenth--;
	return 0;
}

12.遍历线性表

void visit(elemtype e)
{
	printf_s("%d ", e);
	return;
}

void (*q)(elemtype a) = visit;

int List1Traverse(Plist& list,void (*visit1)(elemtype a))
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (list->lenth == 0)
	{
		printf_s("线性表为空\n");
		return 2;
	}
	for (int i = 0; i < list->lenth; i++)
	{
		visit1(list->data[i]);
	}
	printf_s("\n");
	return 0;
}

好了,以上为线性表顺序结构的基本操作,为了方便写入,我又写了一个插入的函数,这个函数只会在线性表的最后插入一个元素。

int List1push_back(Plist& list,elemtype e)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (list->lenth == list->listsize)
	{
		printf_s("线性表已满,无法操作。\n");
		return 2;
	}
	list->data[list->lenth] = e;
	list->lenth++;
	return 0;
}

前面说过,要给你们看一下函数指针的调用。

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
int main()
{
	Plist l;
	int i;
	InitList1(l, 10);
	for (i = 0; i < 10; i++)
	{
		List1push_back(l, i);
	}
	//q在刚刚已经定义为全局变量
	List1Traverse(l,*q);
	
	return 0;
}

输出结果是 :0 1 2 3 4 5 6 7 8 9 \n

呼,好多啊。昨天写了一天,今天又整理了一上午,但感觉还是很值的,函数指针也是在整理复习的时候才知道。C语言很多地方确实没有C++好用,但是没办法,大家多数最开始的时候学的都是C语言,所以我先写了C语言的顺序表操作。

这一篇就写这一部分吧,下一篇会写C语言的链表实现。

对了,放一下总代码:

#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<malloc.h>

typedef int elemtype;

typedef struct List1
{
	elemtype* data;
	int lenth;
	int listsize;
}List1,*Plist;

int InitList1(Plist& list, int lenth)
{
	list = (Plist)malloc(sizeof(List1));
	if (list == NULL )	return 1;
	list->data = NULL;
	list->data = (elemtype*)malloc(sizeof(elemtype) * lenth);
	if ( list->data == NULL)	return 1;
	list->lenth = 0;
	list->listsize = lenth;
	return 0;
}

int DestroyList1(Plist& list)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if((list->data)!=NULL)
		free(list->data);
	free(list);
	list = NULL;
	return 0;
}

int ClearList1(Plist& list)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return -1;
	}
	list->lenth = 0;
	return 0;
}

int List1Empty(Plist& list)
{
	if (list == NULL)	
	{
		printf_s("线性表不存在\n");
		return -1;
	}
	if (list->lenth == 0)	return 1;
	else return 0;
}

int List1Length(Plist& list)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		exit(-1);
	}
	return list->lenth;
}

int GetElemList1(Plist& list,int i,elemtype &e)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (i >= list->lenth)
	{
		printf_s("Out of list range\n");
		return 2;
	}
	e = list->data[i];
	return 0;
}
bool compare(elemtype a, elemtype b)
{
	return a < b;
}

bool (*p)(elemtype a, elemtype b) = compare;

int LocateElemList1(Plist& list, elemtype e, bool (*compare)(elemtype a, elemtype b))
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	for (int i = 0; i <= list->lenth; i++)
	{
		if (compare(e, list->data[i]))
		{
			return i;//compare 表示如果a>b则为1;结果返回的就是线性表中第一个比e小的数字的位置
		}
	}
	return -1;//没有比e小的数字则返回-1;
}


int PriorElem(Plist& list, elemtype cur_e, elemtype& pre_e)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (list->lenth <= 1)
	{
		if (list->lenth == 0)
		{
			printf_s("List is empty\n");
			return 2;
		}
		else if (list->lenth == 1)
		{
			printf_s("Can't find the precursor, because there's only one\n");
			return 3;
		}
	}
	for (int i = 0; i < list->lenth; i++)
	{
		
		if (cur_e == list->data[i])
		{
			if (i != 0)
			{
				pre_e = i - 1;
				return 0;
			}
			else
			{
				printf_s("Can't find the precursor, because it's the first\n");
				return 4;
			}
		}
	}
	printf_s("Can't find the precursor because there's no such element\n");
	return 5;
}

int NextElem(Plist& list, elemtype cur_e, elemtype& next_e)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (list->lenth <= 1)
	{
		if (list->lenth == 0)
		{
			printf_s("List is empty\n");
			return 2;
		}
		else if (list->lenth == 1)
		{
			printf_s("Can't find the successor, because there's only one\n");
			return 3;
		}
	}
	for (int i = 0; i < list->lenth; i++)
	{

		if (cur_e == list->data[i])
		{
			if (i != list->lenth-1)
			{
				next_e = i + 1;
				return 0;
			}
			else
			{
				printf_s("Can't find the successor, because it's the last one\n");
				return 4;
			}
		}
	}
	printf_s("Can't find the successor because there's no such element\n");
	return 5;
}

int List1Insert(Plist& list, int numth, elemtype e)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (list->lenth == list->listsize)
	{
		printf_s("线性表已满,无法操作。\n");
		return 2;
	}
	if (numth > list->lenth)
	{
		printf_s("The location is not valid\n");
		return 3;
	}
	for (int i = list->lenth; i > numth; i--)
	{
		list->data[i] = list->data[i - 1];
	}
	list->data[numth] = e;
	list->lenth++;
	return 0;
}

int List1Delete(Plist& list, int numth, elemtype &e)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (list->lenth == 0)
	{
		printf_s("The list is empty\n");
		return 2;
	}
	if (numth >= list->lenth)
	{
		printf_s("The location is not valid\n");
		return 3;
	}
	e = list->data[numth];
	for (int i = numth; i < list->lenth-1; i++)
	{
		list->data[i] = list->data[i + 1];
	}
	list->lenth--;
	return 0;
}

void visit(elemtype e)
{
	printf_s("%d ", e);
	return;
}

void (*q)(elemtype a) = visit;

int List1Traverse(Plist& list,void (*visit1)(elemtype a))
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (list->lenth == 0)
	{
		printf_s("The list is empty\n");
		return 2;
	}
	for (int i = 0; i < list->lenth; i++)
	{
		visit1(list->data[i]);
	}
	printf_s("\n");
	return 0;
}

int List1push_back(Plist& list,elemtype e)
{
	if (list == NULL)
	{
		printf_s("线性表不存在\n");
		return 1;
	}
	if (list->lenth == list->listsize)
	{
		printf_s("线性表已满,无法操作。\n");
		return 2;
	}
	list->data[list->lenth] = e;
	list->lenth++;
	return 0;
}

int print(Plist &l)
{
	int List1Traverse(Plist & l, void(*visit)(elemtype a));
	List1Traverse(l,*q);
	if (l != NULL)
		printf_s("链表长度为:%d\n", l->lenth);
	return 0;
}
int menu(Plist L)
{
	int print(Plist &L);
	printf_s("=====线性表C语言实现=====\n");
	printf_s("1.创建表		2.删除表\n");
	printf_s("3.初始化表		4.插入元素\n");
	printf_s("5.删除元素		\n");
	printf_s("=====线性表C语言实现=====\n");
	print(L);
	return 0;
}

int main()
{
	int n,a,b;
	Plist L=NULL;
	menu(L);
	while (scanf_s("%d", &n) != EOF)
	{
		switch (n)
		{
		case 1: 
			if (L == NULL)
		{
			
			printf_s("请输入链表的最大长度:");
			scanf_s("%d", &a);
			a=InitList1(L, a);
			if (a == 0)
			{
				printf_s("创建成功,正在返回主菜单\n");
				Sleep(1000);
				system("cls");
				break;
			}
			else 
			{
				printf_s("创建失败,空间申请失败,正在返回主菜单\n");
				break;
			}
		}
			else 
		{
			printf_s("操作失败!线性表已经存在!即将返回主菜单!\n");
			Sleep(1000);
			system("cls");
			break;
		}
		case 2: 
			a=DestroyList1(L);
			if(a==0)
				printf_s("操作成功,即将返回主菜单!\n");
			Sleep(1000);
			system("cls");
			break;
		case 3:
			if (L != NULL)
			{
				printf_s("请输入初始化的数目:");
				scanf_s("%d", &a);
				L->lenth = 0;
				printf_s("请输入初始化的数组:");
				for (int i = 0; i < a; i++)
				{
					scanf_s("%d", &b);
					List1push_back(L, b);
				}
				printf_s("操作成功,即将返回主菜单!\n");
			}
			else printf_s("操作失败,链表不存在,即将返回主菜单!\n");
			Sleep(1000);
			system("cls");
			break;
		case 4:
			if (L != NULL)
			{
				printf_s("请输入插入元素位置和元素值:");
				scanf_s("%d%d", &a, &b);
				a = List1Insert(L, a, b);
				if (a == 0)
					printf_s("操作成功,即将返回主菜单!\n");
			}
			else printf_s("操作失败,链表不存在,即将返回主菜单!\n");
			Sleep(1000);
			system("cls");
			break;
		case 5:
			if (L != NULL)
			{
				printf_s("请输入删除元素的位置:");
				scanf_s("%d", &a);
				a = List1Delete(L, a, b);
				printf_s("删除元素的值为%d\n", b);
				if (a == 0)
					printf_s("操作成功,即将返回主菜单!\n");
			}
			else  printf_s("操作失败,链表不存在,即将返回主菜单!\n");
			Sleep(1000);
			system("cls");
			break;

		default:
			printf_s("输入有误,请重新输入!");
			Sleep(1000);
			system("cls");
			break;
		}
		menu(L);
	}

}

#if 0
int main()
{
	Plist l;
	InitList1(l, 10);
	for (int i = 0; i < 10; i++)
	{
		List1push_back(l, i);
	}
	List1Traverse(l,*q);
	
	return 0;
}
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值