数据结构 — 顺序表

目录

目录

1.什么是顺序表

2.顺序表的模拟实现(C语言)

2.1 代码简介

 SeqList.h 头文件和函数名的声明

 SeqList.c 函数功能的实现

 test.c    函数功能的测试

3. SLErase和SLInsert图解

3.1 SLInsert图解

3.2 SLErase图解


1.什么是顺序表

        顺序表就是数组,用一个对应数据类型的指针,这个指针指向一个动态开辟的内存空间,该数组的的数据类型由使用者决定(一般是结构体)。

  • 顺序表的优点:能够快速的尾插和尾插。
  • 顺序表的缺点:头插头删速度较慢,因为要挪动数据。

2.顺序表的模拟实现(C语言)

2.1 代码简介

  •  SeqList.h 头文件和函数名的声明

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<errno.h>


typedef int SLDatatype;

//因为data存储的是开辟数组的首元素的地址,data和arr都是整形指针类型的元素(int* arr和int* data),data = arr, 相当于把arr中存储的地址赋给了data。
//data和arr存储的值(地址)都相等,解引用是解引用他们存储的值,又因为*arr + 1 == arr[1] ,所以*data+1 == data[1],因为他们存储的值相同,所以他们指向的是同一块数组区域。
//所以data[1] == arr[1]
//data是一个指向数组的指针,为什么data[i]不用解引用直接使用
typedef struct SeqList {
	//
	SLDatatype* a;//开辟一个数组,这是指向动态开辟数组元素的指针。
	int size;//当前存储元素的个数
	int capacity;//容量--空间大小
}SL;



//初始化顺序表
void SLInit(SL* List);

void SLDestory(SL* ps);

//打印顺序表
void SLPrint(SL* ps);

// 顺序表尾插
void SLPushBack(SL* ps, SLDatatype x);

// 顺序表尾删
void SLPopBack(SL* ps);

// 顺序表头插
void SLPushFront(SL* ps, SLDatatype x);

// 顺序表头删
void SLPopFront(SL* ps);

//顺序表任意位置插入
void SLInsert(SL* ps, int pos, SLDatatype x);

//顺序表任意位置删除
void SLErase(SL* ps, int pos);

  •  SeqList.c 函数功能的实现

  • #define _CRT_SECURE_NO_WARNINGS 1
    #include"SeqList.h"
    
    
    
    
    //顺序表初始化
    void SLInit(SL* ps)
    {
    	ps->a = NULL;
    	ps->capacity = ps->size = 0;
    
    }
    
    //打印顺序表
    void SLPrint(SL* ps)
    {
    	//assert(ps != NULL);
    	assert(ps);
    
    	int i = 0;
    	for ( i = 0; i < ps->size; i++)
    	{
    		printf("%d ", ps->a[i]);
    	}
    }
    
    //销毁顺序表
    void SLDestory(SL* ps)
    {
    	if (ps->a)
    	{
    		free(ps->a);
    		ps->a = NULL;
    		ps->capacity = ps->size = 0;
    	}
    
    }
    
    //判定容量
    void CheckCapacity(SL* List)
    {
    	if (List->capacity == List->size)//如果相等证明容量满了
    	{
    		int newcapcity = List->capacity == 0 ? 4 : List->capacity * 2;
    		SLDatatype* tmp = (SLDatatype*)realloc(List->a, newcapcity * sizeof(SL));
    
    		if (tmp == NULL)
    		{
    			perror("realloc fail");
    			exit(-1);
    		}
    		List->a = tmp;
    		List->capacity = newcapcity;
    	}
    }
    
    //顺序表尾插
    void SLPushBack(SL* ps, SLDatatype x)
    {
    	//插入函数复用
    	SLInsert(ps, ps->size, x);
    	//CheckCapacity(ps);
    
    	//ps->a[ps->size] = x;
    	//ps->size++;
    }
    
    
    // 顺序表头插
    void SLPushFront(SL* ps, SLDatatype x)
    {
    
    	//插入函数复用
    	SLInsert(ps, 0, x);
    
    	//CheckCapacity(ps);
    
    	//int end = ps->size - 1;
    	挪动数据
    	//while (end >= 0)
    	//{
    	//	ps->a[end + 1] = ps->a[end];
    	//	--end;
    	//}
    
    	//ps->a[0] = x;
    	//ps->size++;
    }
    
    
    // 顺序表尾删
    void SLPopBack(SL* ps)
    {
    	//Erase复用
    	SLErase(ps, ps->size-1);
    	//assert 暴力检查 直接提示错误
    	//assert(ps->size > 0);
    	//ps->size--;
    }
    
    
    // 顺序表头删
    void SLPopFront(SL* ps)
    {
    	//Erase复用
    	SLErase(ps, 0);
    	/*assert(ps->size > 0);
    	int i = 0;
    	for ( i = 0; i < ps->size-1; i++)
    	{
    		ps->a[i] = ps->a[i + 1];
    	}
    	ps->size--;*/
    }
    
    
    //顺序表任意位置插入
    void SLInsert(SL* ps, int pos, SLDatatype x)
    {
    	CheckCapacity(ps);
    	assert(ps);
    	assert(pos >= 0 && pos <= ps->size);
    	
    	int end = ps->size - 1;
    
    	while (end >= pos)
    	{
    		ps->a[end + 1] = ps->a[end];
    		end--;
    	}
    
    	ps->a[pos] = x;
    	ps->size++;
    	
    }
    
    
    
    //顺序表任意位置删除
    void SLErase(SL* ps, int pos)
    {
    	assert(ps);
    	assert(pos >= 0 && pos < ps->size);
    
    	int begin = pos;
    
    	while (begin < ps->size - 1)
    	{
    		ps->a[begin] = ps->a[begin + 1];
    		begin++;
    	}
    
    	ps->size--;
    }


  •  test.c    函数功能的测试

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"

void test1()
{

	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	
	//SLPopBack(&sl);
	//SLPopBack(&sl);
	//SLPopBack(&sl);
	//SLPopBack(&sl);
	//SLPopBack(&sl);
	//SLPopBack(&sl);
	//
	//SLPushBack(&sl, 1);
	//SLPushBack(&sl, 2);
	//SLPushBack(&sl, 4);

	SLPrint(&sl);
	SLDestory(&sl);

}

void test2()
{
	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPushFront(&sl, 6);

	/*SLPopBack(&sl);
	SLPopFront(&sl);*/

	SLInsert(&sl, 0, 50);

	SLPopBack(&sl);
	SLPopBack(&sl);
	SLPopBack(&sl);
	SLPopBack(&sl);
	SLPopBack(&sl);
	
	//SLPopFront(&sl);

	SLPrint(&sl);
}


int main()
{
	//test1();
	test2();

	//系统对越界的检查,是设岗抽查,越界不一定会报错。
	//int a[10];
	//a[10] = 1;
	//a[11] = 1;
	//a[12] = 1;


	return 0;
}

3. SLErase和SLInsert图解

        因为顺序表中头插 头删 尾插 尾删的功能跟SLInsert 和 SLErase实现差不多,所以暂时目前只做出这两个函数功能的图解。

3.1 SLInsert图解


3.2 SLErase图解

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值