数据结构 | 不定长顺序表

news/2024/5/20 6:27:23 标签: 顺序表, 不定长顺序表, 数据结构

顺序表是在计算机内存中以数组的形式保存的线性表,所以顺序表的存储结构和数组非常类似,而它最显要的特点就是逻辑地址和物理地址都相连。

首先我们来看顺序表及相关函数的定义:

AlterList.h

#pragma once
/*#pragma once是一个比较常用的C/C++预处理指令,只要在头文件的最开始加入这条预处理指令,就能够保证头文件只被编译一次。*/

typedef int ElenType;//重命名int为ElenType
#define SIZE 10;//不定长顺序表的初始大小

typedef struct AlterList
{
	ElenType *data;//指向用户申请的堆区空间
	int count;//元素的个数
	int size;//储存空间的大小
}AlterList ;

void CreateList(AlterList* p);//顺序表的初始化

void AddSpace(AlterList* p);//扩大顺序表的空间

void InsertInHead(AlterList* p,ElenType val);//头插法

void InsertInTail(AlterList* p, ElenType val);//尾插法

void InsertInPos(AlterList* p, ElenType val,int pos);//任意位置插

void PrintList(AlterList* p);//打印顺序表

void DeleteInHead(AlterList* p);//头删

void DeleteInTail(AlterList* p);//尾删

void DeleteInPos(AlterList* p, int pos);//按位置删

void DeleteElement(AlterList* p, ElenType val);//删除重复元素

int FindInPos(AlterList* p, ElenType val);//根据元素查位置

int FindInCondition(AlterList* p, ElenType val, bool(*compare)(ElenType, ElenType));//根据条件查找

void ReverseList(AlterList* p);//逆置

void ClearList(AlterList* P);//清空顺序表

void Destroy(AlterList* p);//销毁顺序表

 接着就是这些函数的实现:

AlterList.cpp

#include"AlterList.h"
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<assert.h>
#include<string.h>

static bool IsFull(AlterList* p)//判断顺序表是否已满
{
	return p->count == p->size;//如果此时实际储存的元素的个数等于顺序表的长度,则顺序表为满
}

static bool IsEmpty(AlterList* p)//判断顺序表是否为空
{
	return p->count == 0;
}

void CreateList(AlterList* p)//顺序表的初始化
{
	assert(p != NULL);
	if (p == NULL)
	{
		return;
	}

	p->count = 0;
	p->size = SIZE;
	p->data = (ElenType*)malloc(sizeof(ElenType) * p->size);
}

void AddSpace(AlterList* p)//扩大顺序表的空间
{
	p->size *= 2;
	p->data = (ElenType*)realloc(p->data, sizeof(ElenType) * p->size);
}

void InsertInHead(AlterList* p, ElenType val)//头插法
{
	InsertInPos(p, val, 0);
}

void InsertInTail(AlterList* p, ElenType val)//尾插法
{
	InsertInPos(p, val, p->count);
}

void InsertInPos(AlterList* p, ElenType val, int pos)//任意位置插
{
	if (pos<0 || pos>p->count)	return;//判端要进行插入的位置pos是否合理

	if (IsFull(p))//如果此时顺序表已满,则先要进行扩容
	{
		AddSpace(p);
	}


	int i = p->count;
	while (i > pos)
	{
		p->data[i] = p->data[i - 1];
		i--;
	}

	p->data[pos] = val;
	p->count++;
}

void PrintList(AlterList* p)//打印顺序表
{
	for (int i = 0; i < p->count; i++)
	{
		printf("%d ", p->data[i]);
	}
	printf("\n");
}

void DeleteInHead(AlterList* p)//删除头
{
	DeleteInPos(p, 0);
}

void DeleteInTail(AlterList* p)//删除尾
{
	DeleteInPos(p, p->count - 1);
}

void DeleteInPos(AlterList* p, int pos)//按位置删除
{
	if (pos<0 || pos>=p->count)	return;//判端要进行删除的位置pos是否合理

	if (IsEmpty(p))	return;//如果此时顺序表为空,则不用删除,直接返回

	while (pos < p->count-1)
	{
		p->data[pos] = p->data[pos + 1];
		pos++;
	}
	p->count--;
}

void DeleteElement(AlterList* p, ElenType val)//删除重复元素
{
	if (IsEmpty(p))	return;
	int i = 0;
	int j = 0;
	while (j < p->count)
	{
		if (p->data[j] == val)
		{
			j++;
		}
		else if (p->data[j] != val)
		{
			if (i != j)
			{
				p->data[i] = p->data[j];
			}
			i++;
			j++;
		}
	}
	p->count -= (j - i);
}

int FindInPos(AlterList* p, ElenType val)//根据元素查位置
{
	if (IsEmpty(p))	return -1;

	for (int i = 0; i < p->count; i++)
	{
		if (p->data[i] == val)
		{
			return i;
		}
	}

	return -1;
}

int FindInCondition(AlterList* p, ElenType val, bool(*compare)(ElenType, ElenType))//根据条件查找
{
	if (IsEmpty(p))	return -1;

	for (int i = 0; i < p->count; i++)
	{
		if (compare(val, p->data[i]))
		{
			return i;
		}
	}
	return -1;
}

void ReverseList(AlterList* p)//逆置
{
	if (IsEmpty(p))	return;

	ElenType t;
	int i = 0;
	int j = p->count - 1;
	for (; i < j; i++, j--)
	{
		t = p->data[i];
		p->data[i] = p->data[j];
		p->data[j] = t;
	}
}

void ClearList(AlterList* p)//清空
{
	if (IsEmpty(p))	return;

	p->count = 0;
}

void Destroy(AlterList* p)//销毁
{
	assert(NULL != P);
	free(p->data);
	p->data=NULL;
	p->count=0;
	p->size=0;
}

 测试用例

main.cpp

#include<stdio.h>
#include"AlterList.h"
bool compare(int a,int b)
{
	if (a == b)	return true;
	return false;
}
int main()
{
	AlterList p;
	CreateList(&p);
	for (int i = 0; i < 10; i++)
	{
		InsertInHead(&p, i+1);
	}
	PrintList(& p);
	InsertInTail(&p, 100);
	PrintList(&p);
	InsertInPos(&p, 200, 3);
	PrintList(&p);
	ReverseList(&p);
	PrintList(&p);
	DeleteInPos(&p, 3);//按位置删
	PrintList(&p);
	DeleteElement(&p, 100);//删除重复元素
	PrintList(&p);
	InsertInTail(&p, 5); 
	PrintList(&p);
	printf("%d\n", FindInCondition(&p, 5, compare));
	DestroyList(&p);
	return 0;
}

 


http://www.niftyadmin.cn/n/1629143.html

相关文章

C++ | C语言和C++的函数符号的生成规则

在C语言中&#xff0c;函数的生成规则和函数名称相关&#xff0c;即只要函数名称相同&#xff0c;就算函数的返回值类型不同&#xff0c;函数的形参不同&#xff0c;最终生成的函数的符号都相同&#xff0c;例如&#xff1a; int Sum(int a,int b) {return ab; }double Sum(do…

BZOJ #3746: [POI2015]Czarnoksiężnicy okrągłego stołu 动态规划

转载请注明出处:http://www.cnblogs.com/TSHugh/p/8823423.html 读完题就会发现p0、1的情况以及n1、2的情况都可以直接判掉,而p2的时候也可以直接构造,那么现在需要的就是当p3且n>3的时候的做法.   容易想到小数据范围下的dfs,但是这难以优化,于是去思考dp的做法.我的思路…

Spring之AOP常用术语的理解

看到《Spring实战》第四版第四章时&#xff0c;对连接点和切点的概念很不理解&#xff0c;多方查阅&#xff0c;理解如下&#xff1a; 在区别连接点和切点之前&#xff0c;先了解什么是通知&#xff08;advice&#xff09; 通知&#xff08;advice&#xff09;&#xff1a; 通…

Ubuntu Apache 域名配置

2018.4.12 Ubuntu Apache 域名配置 承 Ubuntu Apache 配置篇 参考 电子工业出版社&#xff0c; Ubuntu完美应用&#xff0c; 第3版&#xff0c; 及各种大神网上的帖子&#xff0c; 谢谢&#xff01; 一. 序言 一台Web 服务器利用虚拟技术&#xff0c; 把Apache 服务器分成许多…

IDEA搭建mybatis项目之异常:java.io.IOException: Could not find resource mapping/UserMapper.xml

原文链接 由Eclipse转用IDEA真是一把把的辛酸泪&#xff0c;两种编译器看似都是在java开发中中流砥柱的开发工具&#xff0c;但编程这东西失之毫厘差之千里啦&#xff0c;在开发过程中代码出bug不重要&#xff0c;但总是爆些不所云的bug而且与代码关系不大的bug就很气啦&#…

mysql中进行删除操作时用到not in 导致删除不成功

delete from tb_news where id not in ( select max(id) From tb_news Group By title ) 刚开始用这条语句删除一直不成功 然后百度了一下&#xff0c;说是要建立一张临时表 于是进行了以下操作 先建立一个临时表 CREATE TEMPORARY TABLE tmp_news ( id BIGINT(20) ) 然后执…

ssm项目开发过程中跨域问题解决

在写这学期课设时&#xff0c;页面没有采用jsp,前端是对床在他本子上写的&#xff0c;我提供了url给他&#xff0c;他的ajax请求后后台却返回了403,但是这时候我写的jsp测试却没有问题&#xff0c;开始怀疑是表单提交和ajax提交的请求类别不同&#xff0c;于是在网上搜,果然找到…

有道云笔记-程序员的笔记本

下载地址&#xff1a; http://note.youdao.com/ 转载于:https://www.cnblogs.com/liuweipcs/p/8847517.html