0
点赞
收藏
分享

微信扫一扫

数据结构——顺序表(C语言)

艾米吖 04-09 17:30 阅读 1

目录

一、顺序表概念

二、顺序表分类 

        1.静态顺序表

        2.动态顺序表

三、顺序表的实现 

        1.顺序表的结构体定义

        2. 顺序表初始化

        3.顺序表销毁

        4.顺序表的检验

        5.顺序表打印

        6.顺序表扩容

        7.顺序表尾插与头插

        8.尾删与头删

        9.在pos处插入数据

        10.在pos处删除数据

        11.查找数据

四、全部文件及测试结果


一、顺序表概念

二、顺序表分类 

        1.静态顺序表

        概念:使⽤定⻓数组存储元素

        2.动态顺序表

        我们现在是明白了动态顺序表和动态,那我们在用代码实现顺序表时会用那种呢?相信大家此时都已经有了答案,答案很显然是动态顺序表。因为动态顺序表比静态顺序表更加的灵活,不会那么死板,好话不多说,咱们一起来实现吧!

三、顺序表的实现 

        1.顺序表的结构体定义

        这里说明一下:数据结构这方面主要是:数组、指针、结构体这方面内容,因此数据结构可以让我们更好的理解以上内容。

        我们实现顺序表一共会用两个源文件和一个头文件,具体为什么,扫雷里说过可自行查阅。

typedef int seqlist;//大家可想一想把int 命名成seqlist的好处
typedef struct Seqlist
{
	seqlist* a;
	int  size;//有效数据个数
	int capacity;//总容量
}sl;//结构体命名

        2. 顺序表初始化

        当我们拥有了一个顺序表我们必然要对其初始化。

void SLInit(SL* ps)
{
	ps->a = NULL;//初始化把指针置为空
	ps->capacity = ps->size = 0;//元素个数均为零
}

        3.顺序表销毁

        既然把顺序表初始化了,必然要对其销毁

void SLDestroy(SL* ps)
{
	free(ps->a);//顺序表在后续会使用内存函数需free释放
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}

        4.顺序表的检验

        记住写出一个函数就要对其进行检验。

void test1()
{
	void SLInit(SL * ps);
	void SLDestroy(SL * ps);
}

        当我们写出此代码时会报错,这是为什么呢?答案是test文件中只包含了头文件的,没包含源文件的(源文件相互包含会报错),这时我们添加以下代码即可:

SL ps;

        这个时候我们进行调试即可。

        5.顺序表打印

void SLPrint(SL* ps)
{
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d", ps->a[i]);
	}
	peintf("\n");
}

        6.顺序表扩容

        众所周知顺序表有这四大功能:增删查改,要进行第一个功能便要对顺序表经行扩容。

void SLCheckCapacity(SL* ps)
{
	if (ps->capacity == ps->size)
	{
		int newcapacity = ps->capacity > 0 ? 2 * ps->capacity : 4;//这里使用了三目操作符
		//定义一个变量来接收,出第一次外每次扩容二倍
		//为什么是二倍这里不过多推理,可自行了解
		SL* p = (SL *)realloc(ps->a, newcapacity*sizeof(seqlist));
		if (p == NULL)
		{
			printf("扩容失败\n");
			exit(1);
		}
		ps->a = p;
		ps->capacity = newcapacity;
	}
}

        大家可自行对其检验,这里不再进行。

        7.顺序表尾插与头插

        接下来实现顺序表这个功能:

        尾插:

void SLPushBack(SL* ps, seqlist x)
{
	SLCheckCapacity(ps);//检验元素是否满
	ps->a[ps->size++] = x;
	//也可采取以下这种
	//ps->a[pa->size]=x;   
	//ps->size++;
}

        头插:

void SLPushFront(SL* ps, seqlist x)
{
	SLCheckCapacity(ps);//检验元素是否满
	for (int i = ps->size-1; i >0; i--)
	{
		ps->a[i+1] = ps->a[i];
	}
	ps->size++;
	ps->a[0] = x;
}

        8.尾删与头删

        尾删:

void SLPopBack(SL* ps)
{
    assert(ps);
	ps->size--;
}

        头删:

void SLPopFront(SL* ps)
{
	assert(ps);
	for (int i = 1; i < ps -> size; i--)
	{
		ps->a[i-1] = ps->a[i];
	}
	ps->size--;
}

        9.在pos处插入数据

void SLInsert(SL* ps, int pos, seqlist x)
{
	assert(ps);
    SLCheckCapacity(ps);
	for (int i = ps->size-1; i >= pos; i--)
	{
		ps->a[i+1] = ps->a[i];
	}
	ps->a[pos] = x;
	ps->size++;
}

        10.在pos处删除数据

void SLErase(SL* ps, int pos)
{
	assert(pos >= 0 && pos < ps->size && ps);
	for (int i = pos+1; i < ps->size-1; i++)
	{
		ps->a[i-1] = ps->a[i];
	}
	ps->size--;
}

        11.查找数据

int SLFind(SL* ps, seqlist x)
{
	assert(ps);
	for (int i = 0; i < ps->size - 1; i++)
	{
		if (ps->a[i] == x)
		{
			printf("找到了,下标为: %d \n", i + 1);
			return i;
		}
	}
	printf("没找到\n");
	return -1;
}

四、全部文件及测试结果

        seqlist.h:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int seqlist;//大家可想一想把int 命名成seqlist的好处
typedef struct Seqlist
{
	seqlist* a;
	int  size;//有效数据个数
	int capacity;//总容量
}SL;
void SLInit(SL* ps);//顺序表初始化
void SLDestroy(SL* ps);//顺序表销毁
void SLPrint(SL* ps);//顺序表打印
void SLCheckCapacity(SL* ps);//顺序表扩容
void SLPushBack(SL* ps, seqlist x);//尾插
void SLPopBack(SL* ps);//尾删
void SLPushFront(SL* ps, seqlist x);//头插
void SLPopFront(SL* ps);//头删
void SLInsert(SL* ps, int pos, seqlist x);//特定位置插入数据
void SLErase(SL* ps, int pos); //特定位置删除数据
int SLFind(SL* ps, seqlist x);//查找数据

        seqlist.c:

#include"seqlist.h"
void SLInit(SL* ps)
{
	ps->a = NULL;//初始化把指针置为空
	ps->capacity = ps->size = 0;//元素个数均为零
}
void SLDestroy(SL* ps)
{
	free(ps->a);//顺序表在后续会使用内存函数需free释放
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}
void SLPrint(SL* ps)
{
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d", ps->a[i]);
	}
	peintf("\n");
}
void SLCheckCapacity(SL* ps)
{
	if (ps->capacity == ps->size)
	{
		int newcapacity = ps->capacity > 0 ? 2 * ps->capacity : 4;//这里使用了三目操作符
		//定义一个变量来接收,出第一次外每次扩容二倍
		//为什么是二倍这里不过多推理,可自行了解
		SL* p = (SL *)realloc(ps->a, newcapacity*sizeof(seqlist));
		if (p == NULL)
		{
			printf("扩容失败\n");
			exit(1);
		}
		ps->a = p;
		ps->capacity = newcapacity;
	}
}
void SLPushBack(SL* ps, seqlist x)
{
	SLCheckCapacity(ps);//检验元素是否满
	ps->a[ps->size++] = x;
	//也可采取以下这种
	//ps->a[pa->size]=x;   
	//ps->size++;
}
void SLPushFront(SL* ps, seqlist x)
{
	SLCheckCapacity(ps);//检验元素是否满
	for (int i = ps->size-1; i >0; i--)
	{
		ps->a[i+1] = ps->a[i];
	}
	ps->size++;
	ps->a[0] = x;
}
void SLPopBack(SL* ps)
{
	assert(ps);
	ps->size--;
}
void SLPopFront(SL* ps)
{
	assert(ps);
	for (int i =  1; i <ps->size; i--)
	{
		ps->a[i-1] = ps->a[i];
	}
	ps->size--;
}
void SLInsert(SL* ps, int pos, seqlist x)
{
	assert(ps);
	SLCheckCapacity(ps);
	for (int i = ps->size-1; i >= pos; i--)
	{
		ps->a[i+1] = ps->a[i];
	}
	ps->a[pos] = x;
	ps->size++;
}
void SLErase(SL* ps, int pos)
{
	assert(pos >= 0 && pos < ps->size && ps);
	for (int i = pos+1; i < ps->size-1; i++)
	{
		ps->a[i-1] = ps->a[i];
	}
	ps->size--;
}
int SLFind(SL* ps, seqlist x)
{
	assert(ps);
	for (int i = 0; i < ps->size - 1; i++)
	{
		if (ps->a[i] == x)
		{
			printf("找到了,下标为: %d \n", i + 1);
			return i;
		}
	}
	printf("没找到\n");
	return -1;
}

        test.c:

#include"seqlist.h"
void menu()
{
	printf("***********************\n");
	printf("**1.尾插     2.尾删****\n");
	printf("**3.头插     4.头删****\n");
	printf("**5.固定插入 6.固定删除\n");
	printf("**7.查找     0.删除顺序表\n");
	printf("**0.销毁并退出*********\n");
}
int main()
{
	SL ps;
	SeqListInit(&ps);
	SeqListPushBack(&ps, 4);
	SeqListPushBack(&ps, 5);
	SeqListPushBack(&ps, 6);
	SeqListPushFront(&ps, 3);
	SeqListPushFront(&ps, 2);
	SeqListPushFront(&ps, 1);
	SeqListPrint(&ps);//顺序表初始化
	int input;
	do 
	{
		menu();
		printf("please input your choice:");
		scanf("%d", &input);
		Seqlist x;
		int pos;
		int find;
		int getfind;
		switch (input)//顺序表输入测试
		{
		case 0:
			SeqListDestroy(&ps);
			break;
		case 1:
			scanf("%d", &x);
			SeqListPushBack(&ps, x);
			SeqListPrint(&ps);
			break;
		case 2:
			SeqListPopBack(&ps);
			SeqListPrint(&ps);
			break;
		case 3:
			scanf("%d", &x);
			SeqListPushFront(&ps, x);
			SeqListPrint(&ps);
			break;
		case 4:
			SeqListPopFront(&ps);
			SeqListPrint(&ps);
			break;
		case 5:
			scanf("%d", &pos);
			scanf("%d", &x);
			SeqListInsert(&ps, pos, x);
			SeqListPrint(&ps);
			break;
		case 6:
			scanf("%d", &pos);
			SeqListErase(&ps, pos);
			SeqListPrint(&ps);
			break;
		case 7:
			scanf("%d", &find);
			getfind = SeqListFind(&ps, find);
			printf("%d", getfind);
			printf("\n");
			break;
		default:
			printf("error input\n");
			break;
		}
	} while (input);
	return 0;
}

        完!

举报

相关推荐

0 条评论