【C语言】实现顺序表的增、删、查、改

在实现顺序表之前先来了解几个概念。

1、线性表

n(n>=0)个数据元素组成的一个有限序列,可以在其任何位置上进行插入和删除操作的线性数据结构。

从数据在物理内存存储形式上线性表可分为:顺序表和链表。


由上图可看出:

线性表中数据与数据之间存在一对一的关系,即除第一个元素和最后一个元素外,每个元素都有唯一的直接前驱和唯一的直接后继,第一个元素没有前驱,最后一个元素没有后继。

2、顺序表

用一段地址连续的存储单元依次存储数据元素的线性结构。

地址连续的空间,一般情况下采用数组,数组有静态数组和动态数组,顺序表也分静态顺序表和动态顺序表。

3、顺序表的实现

以下先实现静态顺序表的增删查改。

seqlist.h

首先,保证编译一次,需要添加下面代码;

#pragma once

创建结构体

#define SeqListMaxSize 1000   //定义宏,方便后续更改顺序表元素大小

typedef char SeqListType;
typedef struct seqlist
{
	SeqListType data[SeqListMaxSize];
	size_t size; //线性表中的有效元素
}SeqList;

这里需要注意一点,size_t占几个字节?

(1)在32位操作系统中,占4个字节;

(2)在64位操作系统中,占8个字节;

下面开始实现具体的功能函数,需要注意的就是函数的命名,以下使用的函数功能名称,是约定俗成的,以后看到这类函数名,功能也是类似的。

void SeqListInit ( SeqList * seqlist );//初始化
void SeqListPushBack(SeqList * seqlist, SeqListType value);//往顺序表尾部插入value元素
void SeqListPopBack(SeqList *seqlist);//尾删
void SeqListPushFront(SeqList *seqlist,SeqListType value);//头插
void SeqListPopFront(SeqList *seqlist);//头删	
void SeqListInsert(SeqList *seqlist, size_t pos, SeqListType value);//在pos位置插入value元素
void SeqListErase(SeqList *seqlist, size_t pos);//删除pos位置的元素
void SeqListRead(SeqList *seqlist, size_t pos);//读取pos位置的元素
void SeqListAlter(SeqList *seqlist, size_t pos, SeqListType value);//更改pos位置处的元素为value
size_t SeqListFindIndex(SeqList *seqlist, SeqListType value);//查找元素value的下标	
void SeqListRemove(SeqList *seqlist, SeqListType to_remove);//删除顺序表中to_remove的值
void SeqListRemoveAll(SeqList *seqlist, SeqListType to_remove);//删除顺序表中全部得to_remove的值
void SeqListBubbleSort(SeqList *seqlist);//冒泡排序
//函数指针
typedef int(*Cmp)(SeqListType a, SeqListType b);
//如果a和b满足比较规则,返回1,否则返回0.
//如果是升序排列,a<b就称为满足比较规则
void SeqListBubbleSortEx(SeqList *seqlist, Cmp cmp);

接下来是函数的具有实现,在seqlist.c 中实现:

seqlist.c
//顺序表初始化
void SeqListInit(SeqList * seqlist)
{
	if (seqlist == NULL)
	{//非法输入
		return;
	}
	seqlist->size = 0;
}
//往顺序表尾部插入元素value
void SeqListPushBack(SeqList * seqlist, SeqListType value)
{
	if (seqlist == NULL)
	{
		return;
	}
	if (seqlist->size >= SeqListMaxSize)
	{
		//顺序表已满
		return;
	}
	seqlist->data[seqlist->size]= value;
	seqlist->size++;
}
//尾删
void SeqListPopBack(SeqList *seqlist)
{
	if (seqlist == NULL)
	{
		return;
	}
	if (seqlist->size == 0)
	{//顺序表是空
		return;
	}
	--seqlist->size;
	return;
}
//头插
void SeqListPushFront(SeqList *seqlist, SeqListType value)
{
	if (seqlist == NULL)
	{
		return;
	}
	if (seqlist->size >= SeqListMaxSize)
	{//满了
		return;
	}
	++seqlist->size;//最好实现前置++,原因先不谈
	//seqlist->size++;
	size_t i = seqlist->size - 1;
	for (; i > 0; --i)
	{
		seqlist->data[i] = seqlist->data[i - 1];
	}
	seqlist->data[0] = value;
	return;
}
//头删
void SeqListPopFront(SeqList *seqlist)
{
	if (seqlist == NULL)
	{
		return;
	}
	if (seqlist->size == 0)
	{//空
		return;
	}
	size_t i = 0;
	for (; i < seqlist->size - 1; ++i)
	{
		seqlist->data[i] = seqlist->data[i + 1];
	}
	--seqlist->size;
	return;
}
//在pos位置插入value元素
void SeqListInsert(SeqList *seqlist, size_t pos, SeqListType value)
{
	if (seqlist == NULL)
	{
		return;
	}
	if (pos >= seqlist->size)
	{//越界了
		return;
	}
	if (seqlist->size >= SeqListMaxSize)
	{//满了
		return;
	}
	if (pos == 0)
	{//如果pos=0时,后面的--i为-1时,size_t是无符号长整型,负数为一个超级大的数值
		//故转为头插函数
		SeqListPushFront(&seqlist, value);
	}
	++seqlist->size;
	size_t i = seqlist->size - 1;
	for (; i - 1 >= pos; --i)
	{
		seqlist->data[i] = seqlist->data[i - 1];
	}
	seqlist->data[pos] = value;
	return;
}
//删除pos位置的元素
void SeqListErase(SeqList *seqlist, size_t pos)
{
	if (seqlist == NULL)
	{
		return;
	}
	if (seqlist->size == 0)
	{//空
		return;
	}
	if (pos >= seqlist->size)
	{//pos值越界
		return;
	}
	size_t i = pos;
	for (; i < seqlist->size - 1; ++i)
	{
		seqlist->data[i] = seqlist->data[i + 1];
	}
	--seqlist->size;
	return;
}
//读取pos位置的元素
void SeqListRead(SeqList *seqlist, size_t pos)
{
	if (seqlist == NULL)
	{
		return;
	}
	if (seqlist->size == 0)
	{
		return;
	}

	printf("[%c]\n", seqlist->data[pos]);
}
//更改pos位置处的元素为value
void SeqListAlter(SeqList *seqlist, size_t pos, SeqListType value)
{
	if (seqlist == NULL)
	{
		return;
	}
	if (seqlist->size == 0)
	{
		return;
	}
	seqlist->data[pos] = value;
}
//查找元素value的下标
size_t SeqListFindIndex(SeqList*seqlist, SeqListType value)
{
	if (seqlist == NULL)
	{
		return;
	}
	if (seqlist->size == 0)
	{
		return;
	}
	size_t i = 0;
	for (; i < seqlist->size; ++i)
	{
		if (seqlist->data[i] == value)
			return i;
	}
	return -1;
}
//删除顺序表中to_remove的值
void SeqListRemove(SeqList *seqlist, SeqListType to_remove)
{
	if (seqlist == NULL)
	{
		return;
	}
	size_t pos = SeqListFindIndex(seqlist, to_remove);
	if (pos == (size_t)-1)
	{
		return;//没找到
	}
	SeqListErase(seqlist, pos);
	return;
}
//删除顺序表中全部得to_remove的值
void SeqListRemoveAll(SeqList *seqlist, SeqListType to_remove)
{
	if (seqlist == NULL)
	{
		return;
	}
	while (1)
	{
		size_t pos = SeqListFindIndex(seqlist, to_remove);
		if (pos == (size_t)-1)
		{
			break;
		}
		SeqListErase(seqlist, pos);
	}
}
//交换函数
void Swap(SeqListType *a, SeqListType *b)
{
	SeqListType tmp = *a;
	*a = *b;
	*b = tmp;
}
//冒泡排序
void SeqListBubbleSort(SeqList *seqlist)
{
	if (seqlist == NULL)
	{
		return;
	}
	size_t count = 0;//count 表示冒泡次数
	for (; count < seqlist->size; ++count)
	{
		size_t cur = 0;//当前位置
		for (; cur < seqlist->size - 1 - count; ++cur)
		{
			if (seqlist->data[cur]>seqlist->data[cur + 1])
			{
				Swap(&seqlist->data[cur], &seqlist->data[cur + 1]);
			}
		}
	}
}

上传冒泡排序代码总乱序。。。保险起见,贴个图。。

贴个图总不至于再给我乱吧

//指定规则的排序
void SeqListBubbleSortEx(SeqList *seqlist, Cmp cmp)
{
	if (seqlist == NULL)
	{
		return;
	}
	size_t count = 0;//count 表示冒泡次数
	for (; count < seqlist->size; ++count)
	{
		size_t cur = 0;//当前位置
		for (; cur < seqlist->size - 1 - count; ++cur)
		{
			if (!cmp(seqlist->data[cur],seqlist->data[cur+1]))
			{
				Swap(&seqlist->data[cur], &seqlist->data[cur + 1]);
			}
		}
	}
}











猜你喜欢

转载自blog.csdn.net/weixin_38682277/article/details/79596325