C\C++数据结构 001 线性表的顺序存储实现

线性表的顺序存储实现

/*
 *运行平台:Visual Studio 2015(Debug x86)
 *参考资料:《大话数据结构》,传智扫地增C\C++数据结构课程

*/


一、线性表的形象描述

  线性表,从名字上你就能感觉到,是具有像线一样的性质的表。在广场上,有很多人分散在各处,当中有些是小朋友,可也有很多大人,甚至还有不少宠物,这些小朋友的数据对于整个广场人群来说,不能算是线性表的结构。但像刚才提到的那样,一个班级的小朋友,一个跟着一个排着队,有一个打头,有一个收尾,当中的小朋友每一个都知道他前面一个是谁,他后面一个是谁,这样如同有一根线把他们串联起来了,就可以称之为线性表。(摘抄自大话数据结构)

二、线性表顺序存储的概念

一段地址 连续 的存储单元依次存储线性表的数据元素,如图所示。
在这里插入图片描述

注意:此时容量和长度是两个不同的概念。

  1. 容量:存储单元的个数,这个在你建立线性表的时候就确定了,不可修改,上图中的容量为10
  2. 长度:已使用的存储单元的个数,可以改变,上图中长度为8

三、插入元素算法设计思路

如下图所示,插入算法分为三步:
   ①、插入前,该位置以及其后面的元素都需要往后移动一个单元(最后一个元素开始移动)。
   ②、移动完毕后,插入新元素。
   ③、当插入的位置大于当前线性表的长度时,程序自动插入最后一个位置。
在这里插入图片描述

四、代码实现

1、main.c测试文件

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "seqlist.h"

/* 存储的数据 */
typedef struct _Teacher
{
	int age;
	char name[64];
}Teacher;

void main()
{
	SeqList* list = NULL;
	Teacher t1, t2, t3, t4;
	Teacher *tmp = NULL;
	int i;
	int ret = 0;
	t1.age = 11;
	t2.age = 12;
	t3.age = 13;
	t4.age = 14;

	list = SeqList_Create(10);	//创建线性表
	if(list == NULL)
	{
		printf("func SeqList_Create err \n");
		return ;
	}
	
	/* 头插法(存储的是Teacher结构体变量的地址) */
	ret = SeqList_Insert(list, (SeqListNode*)&t1, 0);
	ret = SeqList_Insert(list, (SeqListNode*)&t2, 0);
	ret = SeqList_Insert(list, (SeqListNode*)&t3, 0);
	ret = SeqList_Insert(list, (SeqListNode*)&t4, 0);
	
	/* 读取线性表内容 */
	for(i=0; i<SeqList_Length(list); i++)
	{
		tmp = (Teacher *)SeqList_Get(list, i);
		printf("tmp->age:%d\n",tmp->age);
	}
	
	/* 删除2位置的单元,后读取 */
	SeqList_Delete(list, 2);
	for(i=0; i<SeqList_Length(list); i++)
	{
		tmp = (Teacher *)SeqList_Get(list, i);
		printf("tmp->age:%d\n",tmp->age);
	}
	
	SeqList_Clear(list);	//清空线性表
	SeqList_Destroy(list);	//释放线性表资源
	system("pause");
}

2、seqlist.h线性表头文件

#ifndef  __MY_SEQLIST_H__ 
#define __MY_SEQLIST_H__

typedef void SeqList;
typedef void SeqListNode;

SeqList* SeqList_Create(int capacity);	//创建线性表

void SeqList_Destroy(SeqList* list);	//释放线性表资源

void SeqList_Clear(SeqList* list);		//清空线性表

int SeqList_Length(SeqList* list);		//返回线性表长度

int SeqList_Capacity(SeqList* list);	//返回线性表容量

int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);	//插入元素

SeqListNode* SeqList_Get(SeqList* list, int pos);		//返回第一个值为pos的单元的地址

SeqListNode* SeqList_Delete(SeqList* list, int pos);	//删除指定元素

#endif  //__MY_SEQLIST_H__

3、seqlist.c线性表功能实现文件

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "seqlist.h"

//在结构体中套1级指针
typedef struct _tag_SeqList
{
	int length;
	int capacity;
	unsigned int *node;   
}TSeqList;

/* 创建线性表 */
SeqList* SeqList_Create(int capacity)
{
	TSeqList* mlist = NULL;
	
	//开辟内存
	mlist = (TSeqList *)malloc(sizeof(TSeqList));
	if(mlist == NULL)
	{
		printf("func SeqList_Create() err: -1");
		return NULL;
	}
	memset(mlist, 0, sizeof(TSeqList));

	mlist->node = (unsigned int *)malloc(sizeof(unsigned int *)*capacity);	// ==>int node[capacity]
	if(mlist->node == NULL)
	{
		printf("func SeqList_Create() err: -2");
		return NULL;
	}
	memset(mlist->node, 0, sizeof(unsigned int *)*capacity);
	
	mlist->capacity = capacity;
	mlist->length = 0;

	return mlist;
}

/* 释放线性表资源 */
void SeqList_Destroy(SeqList* list)
{
	TSeqList* mlist = NULL;
	if (list == NULL)
	{
		printf("func SeqList_Destroy() err\n");
		return;
	}

	mlist = (TSeqList*)list;
	if(mlist->node != NULL)
	{
		free(mlist->node);
		mlist->node = NULL;
	}

	free(mlist);
	mlist->capacity = 0;
	mlist->length = 0;
	mlist = NULL;
}

/* 清空链表,回到初始化状态 */
void SeqList_Clear(SeqList* list)
{
	TSeqList* mlist = NULL;
	if (list == NULL)
	{
		return;
	}
	mlist = (TSeqList*)list;

	//清空链表
	memset(mlist->node, 0, sizeof(unsigned int *)*mlist->capacity);
	mlist->length = 0;
}

/* 返回线性表长度 */
int SeqList_Length(SeqList* list)
{
	TSeqList* mlist = NULL;
	if (list == NULL)
	{
		return -1;
	}
	mlist = (TSeqList*)list;

	return mlist->length;
}

/* 返回线性表容量 */
int SeqList_Capacity(SeqList* list)
{
	TSeqList* mlist = NULL;
	if (list == NULL)
	{
		return -1;
	}
	mlist = (TSeqList*)list;

	return mlist->capacity;
}

/* 插入元素 */
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)
{
	TSeqList* mlist = NULL;
	int i;

	if (list == NULL || node == NULL || pos < 0)
	{
		printf("func SeqList_Insert() err: -1\n");
		return -1;
	}

	mlist = (TSeqList *)list;

	//容错纠正
	if(pos > mlist->length)
	{
		pos = mlist->length;
	}

	//先后移
	for(i=mlist->length; i>pos; i--)
	{
		mlist->node[i] = mlist->node[i-1];
	}

	//再插入
	mlist->node[pos] = (unsigned int)node;
	mlist->length++;
	return 0;
}

/* 返回第一个值为pos的单元的地址 */
SeqListNode* SeqList_Get(SeqList* list, int pos)
{
	TSeqList *mlist = NULL;

	if (list == NULL || pos < 0)
	{
		printf("func SeqList_Get() err: -1\n");
		return NULL;
	}

	mlist = (TSeqList *)list;
	return (SeqListNode*)mlist->node[pos];
}

/* 删除指定元素 */
SeqListNode* SeqList_Delete(SeqList* list, int pos)
{
	TSeqList *mlist = NULL;
	SeqListNode *ret = 0;
	int i;

	if (list == NULL || pos < 0)
	{
		printf("func SeqList_Get() err: -1\n");
		return NULL;
	}
	mlist = (TSeqList *)list;
	if (pos > mlist->length)
	{
		printf("func SeqList_Get() err: -2\n");
		return NULL;
	}

	//先缓存
	ret = (SeqListNode *)mlist->node[pos];

	//后后移
	for(i = pos; i<mlist->length; i++)
	{
		mlist->node[i-1] = mlist->node[i];
	}

	mlist->length--;
	return ret;
}

五、线性表顺序存储的分析

1、优点

  • 无需为线性表中的逻辑关系增加额外的空间
  • 可以快速的获取表中合法位置的元素

2、缺点

  • 插入和删除操作需要移动大量元素
  • 当线性表长度变化较大时难以确定存储空间的容量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值