数据结构 | 不定长顺序表

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

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

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;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值