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

顺序表的特点

优点:
1.实现简单
2.支持随机(下标)访问
缺点:
1.插入数据时间复杂度O(n),但是尾插O(1)
2.删除数据O(n),但是尾删O(1)

该顺序表由dsqlist.h + dsqlist.cpp + main.cpp 组成

dsqlist.h文件 //头文件,存放数据结构和函数的声明

#pragma once//预防头文件被重复引用,每个头文件必须在最上面写这一句

typedef struct DsqList
{
	int* elem;//保存动态内存的地址
	int length;//有效数据个数
	int listsize;//总单元格数量
}DsqList, * PDsqList;

#define INITSIZE 10

//初始化
//void InitDsqlist(DsqList *ps);
void InitDsqlist(PDsqList ps);//PDsqList == DsqList *

//销毁
void Destroy(PDsqList ps);

//清空数据
void Clear(PDsqList ps);

//查找val,找到返回下标,失败返回-1
int Search(const PDsqList ps, int val);

//判断是否为空
bool IsEmpty(const PDsqList ps);

//获取长度,有效数据个数
int GetLength(const PDsqList ps);

//获取i下标的值
//int GetElem(const PDsqList ps, int i);
bool GetElem(const PDsqList ps, int i, int* rtval);

//获取i下标的前驱
//int GetPrio(const PDsqList ps, int i);
bool GetPrio(const PDsqList ps, int i, int* rtval);

//获取i下标的后继
//int GetNext(const PDsqList ps, int i);
bool GetNext(const PDsqList ps, int i, int* rtval);

//在i下标插入数据val
bool Insert(PDsqList ps, int i, int val);

//删除i下标的值
bool DelPos(PDsqList ps, int i, int* rtval);

//删除val
bool DelVal(PDsqList ps, int val);

//输出
void Show(const PDsqList ps);

dsqlist.cpp文件
//源文件,存放具体实现
//不定长顺序表,可以扩容realloc

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include<malloc.h>
#include "dsqlist.h"//引用本项目的头文件用""

//初始化
void InitDsqlist(PDsqList ps)//PDsqList == DsqList *
{
	assert(ps != NULL);
	if (ps == NULL)
		return;

	ps->elem =  (int*)malloc(INITSIZE * sizeof(int));
	assert(ps->elem != NULL);

	ps->length = 0; 
	ps->listsize = INITSIZE;
}

//销毁
void Destroy(PDsqList ps)
{
	free(ps->elem);
	ps->elem = NULL;//不写的话,就是野指针
	ps->length = 0;
	ps->listsize = 0;
	//ps = NULL;//没有意义,传指针,解引用
}

//清空数据
void Clear(PDsqList ps)
{
	ps->length = 0;
}

//判断是否为空
bool IsEmpty(const PDsqList ps)
{
	return ps->length == 0;
}

//查找val,找到返回下标,失败返回-1
int Search(const PDsqList ps, int val)
{
	//从头到尾遍历
	for (int i = 0; i < ps->length; i++)
	{
		if (ps->elem[i] == val)
			return i;			
	}
	return -1;	
}

//获取长度,有效数据个数
int GetLength(const PDsqList ps)
{
	return ps->length;
}

//获取i下标的值
//int GetElem(const PDsqList ps, int i)
bool GetElem(const PDsqList ps, int i,int *rtval)//注意函数设计
{
	if (i < 0 || i >= ps->length)
		return false;
	*rtval = ps->elem[i];
	return true;
}

//获取i下标的前驱
bool GetPrio(const PDsqList ps, int i, int* rtval)
{
	if (i <= 0 || i > ps->length)
		return false;
	*rtval = ps->elem[i-1];
	return true;
}

//获取i下标的后继
bool GetNext(const PDsqList ps, int i, int* rtval)
{
	if (i < 0 || i >= ps->length-1)
		return false;
	*rtval = ps->elem[i + 1];
	return true;
}

//判满,内部使用
static bool IsFull(const PDsqList ps)
{
	return ps->length == ps->listsize;
}

//扩容,将容量扩大到原来的2倍
static void Inc(PDsqList ps)
{
	ps->elem = (int*)realloc(ps->elem, ps->listsize * 2 * sizeof(int));
	assert(ps->elem != NULL);

	//ps->length;不变 
	ps->listsize *= 2;
}

//在i下标插入数据val
bool Insert(PDsqList ps, int i, int val)
{
	if (i<0 || i>ps->length)
		return false;
	if (IsFull(ps))
		Inc(ps);
	//移动后面的数据
	for (int j = ps->length - 1; j >= i; j--)
	{
		ps->elem[j + 1] = ps->elem[j];
	}
	//插入新数据
	ps->elem[i] = val;
	//有效数据个数+1
	++ps->length;

	return true;
}

//删除i下标的值,rtval将删除的值带出
bool DelPos(PDsqList ps, int i, int* rtval)
{
	//判断i是否合法
	if (i < 0 || i >= ps->length)
		return false;
	//后面的数据往前移动
	if(rtval!=NULL)//**********判空
		rtval = &ps->elem[i];
	for (int p = i; p + 1 < ps->length; p++)//p+1*******p<length的话会越界
	{
		ps->elem[p] = ps->elem[p + 1];
	}
	//有效数据个数-1
	ps->length -= 1;
	return true;
}

//删除val
bool DelVal(PDsqList ps, int val)
{
	int i = Search(ps, val);
	if (i < 0)
		return false;
	return DelPos(ps,i, NULL);
}

//输出
void Show(const PDsqList ps)
{
	for (int i = 0; i < ps->length; i++)
	{
		printf("%d ", ps->elem[i]);
	}
	printf("\n\n");
}

main.cpp文件 //测试

#include "dsqlist.h"
int main()
{
	DsqList ds;
	int* r = {};
	InitDsqlist(&ds);
	for (int i = 0; i < 20; i++)
	{
		Insert(&ds, i, i + 1);
	}
	printf("最初\n");
	Show(&ds);

	printf("有效数据数:%d\n", GetLength(&ds));

	printf("在5下标插入100\n");
	Insert(&ds, 5, 100);
	Show(&ds);
	printf("有效数据数:%d\n", GetLength(&ds));

	printf("删除100\n");
	DelVal(&ds, 100);
	Show(&ds);

	printf("删除5下标的值\n");
	DelPos(&ds,5, r);
	Show(&ds);
	printf("有效数据数:%d\n", GetLength(&ds));

	Clear(&ds);
	Show(&ds);

	Destroy(&ds);
	Show(&ds);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值