「数据结构」线性表(C语言):顺序表

前言

  • 什么是抽象数据类型
    抽象数据类型(Abstract Data Type,简称ADT),具有类似行为的特定数据结构的数学模型;抽象数据类型包括数据元素、数据元素之间的关系以及对数据元素的一些操作,即带有一些操作的数据对象的集合;而在C语言中,利用结构体(struct)来表示数据结构。

顺序表ADT实现

对表的操作( 所有操作前提是顺序表存在)

  • CreateList():创建顺序表;
/*创建顺序表时使用malloc函数可以为表在堆中动态分配空间
(malloc函数可以使用也可以不用)*/
//创建表
SeqList *CreateList()
{
	SeqList *seqList;
	int length,i;
	printf("请输入顺序表的长度:");
	scanf("%d",&length);
	if(length > MAX_SIZE)
	{
		printf("输入不合法\n");
	}
	else
	{
		seqList = (SeqList *)malloc(sizeof(SeqList));
		seqList->last = length;
		for(i = 0; i < length; i++)
		{
			scanf("%d",&seqList->elem[i]);
		}
		printf("创建成功!\n");
		return seqList;
	}
}
  • PrintList(SeqList *L):打印顺序表;
//打印表
void PrintList(SeqList *L)
{	
	int i;
	if(IsEmpty(L))
	{
		printf("顺序表为空!\n");
	}
	else
	{
		printf("输出顺序表:\n");
		for(i = 0; i < L->last; i++)
		{
			printf("%d ",L->elem[i]);
		}
		printf("\n");
	}
}
  • DestroyList(SeqList *L):销毁顺序表,即删除顺序表;
/* 销毁表时使用free函数清空顺序表在堆中的空间,并需要将指针置空*/
//删除表
void DestroyList(SeqList *L)
{
	free(L);
	printf("删除成功!\n");
}
  • ClearList(SeqList *L):清空顺序表;

/* 清空顺序表即将顺序表的长度置为0,线性表规定长度为0表示空表*/
//置空表
void ClearList(SeqList *L)
{
	L->last = 0;
	printf("置空完成!\n");
}

对表中元素的操作(操作的前提是顺序表不为空)

  • Locate(SeqList *L, int x):定位元素,输出元素在顺序表中的位置;
//定位元素
void Locate(SeqList *L, int x)
{
	int i;
	for(i = 0; i < L->last; i++)
	{
		if(L->elem[i] == x)
			break;
	}
	if(i == L->last)
	{
		printf("未找到元素!\n");
	}
	else
	{
		printf("查找结果:%d\n",i+1);
	}
}
  • GetData(SeqList *L, int i):查找元素,输出指定位置的元素;
//查找元素
void GetData(SeqList *L, int i)
{
	if(i >= L->last || i <= 0)
	{
		printf("查找位置不合法!\n");
	}
	else
	{
		printf("查找结果:%d\n",L->elem[i-1]);
	}
}
  • InsList(SeqList *L, int i, int x):插入元素,插入元素到指定位置;
//插入元素
void InsList(SeqList *L, int i, int x)
{
	if(L->last+1 > MAX_SIZE)
	{
		printf("无法插入元素!\n");
	}
	else
	{
		if(i > L->last+1)
		{
			printf("插入位置错误,无法插入!!\n");
		}
		else
		{
			int j;
			for(j = L->last; j >= i; j-- )
			{
				L->elem[j] = L->elem[j-1];
			}
			L->elem[i-1] = x;
			L->last++;
			printf("插入成功!\n");
		}
	}
}
  • DelList(SeqList *L, int i):删除指定位置元素;
//删除指定位置元素
void DelList(SeqList *L, int i)
{
	if(i >= L->last || i <= 0)
	{
		printf("删除位置不合法!\n");
	}
	else
	{
		for(; i < L->last; i++)
		{
			L->elem[i - 1] = L->elem[i];
		}
		L->last--;
		printf("删除成功!\n");

	}
}
  • DelData(SeqList *L, int x):删除指定元素;
//删除指定元素
void DelData(SeqList *L, int x)
{
	int i;
	for(i = 0; i < L->last; i++)
	{
		if(L->elem[i] == x)
			break;
	}
	if(i == L->last)
	{
		printf("未找到删除的元素!\n");
	}
	else
	{
		for(i ; i < L->last-1; i++)
		{
			L->elem[i] = L->elem[i+1];
		}
		L->last--;
		printf("删除成功!\n");
	}
}

顺序表的存储结构

顺序表存储结构
顺序表特点:物理存储结构上连续,逻辑结构上相邻。
顺序表的数据结构:

typedef struct
{
	//顺序表数据结构
	int elem[MAX_SIZE];
	int last;
}SeqList;
//可以根据需要定义顺序表中元素的类型

顺序表插入操作实现

不论元素插入到什么位置,插入点后的元素需要后移。
插入时元素后移

如何判断顺序表是否存在

定义一个结构体指针,初始状态结构体指针指向为NULL,即为空指针;使用malloc函数为顺序表分配空间,此时结构体指针指向的时堆中动态分配的空间;通过判断结构体指针是否为空来说明顺序表是否存在,销毁顺序表时,调用free函数清空堆中的空间,同时将结构体指针指向空。(关于C语言空指针深入了解

顺序表中指针传递问题

#include<stdio.h>
void test(int *p)
{
	p = NULL;
}
int main()
{
	int *p;
	test(p);
	if(p == NULL)
	{
		printf("这是空指针!\n");
	}
	else
	{
		printf("这是野指针!\n");
	}
	return 0;
}
//结果输出为野指针

在代码中首先在主函数中定义了一个指针,然后我们调用函数将指针传递过去,在子函数中使用p= NULL(目的将指针设为空指针),但是主函数中的指针却并没有指向NULL(C语言指针传递问题
原因:传递指针,函数会先复制一个指针,两个指针指向同一个地址,虽然子函数的指向改变了,但是并不会影响到主函数中的指针。

全部代码

GitHub地址:Sequence.cpp

运行结果

运行结果

发布了20 篇原创文章 · 获赞 75 · 访问量 6908

猜你喜欢

转载自blog.csdn.net/weixin_42089228/article/details/103497461