C语言数据结构-1.线性表之顺序存储结构

本文介绍了C语言数据结构中的线性表,包括线性表的基本概念、特性,以及顺序存储结构的增删查操作。线性表是具有相同类型元素的有限序列,顺序存储结构通过数组实现,插入、删除和查找操作直接作用于数组。

C语言数据结构

一、算法的基本知识


1.编写程序的基本规则

①尽量少使用内存空间。②尽量少的代码量解决问题。

2.数据的特点

①必须能够输入到计算机。②必须能够被程序处理。

3.数据的几个概念

①数据元素:组成数据的基本单位。②数据项:一个元素由若干个数据组成。③数据对象:性质相同的数据元素的集合。

如下图:

4.数据的结构的组成

(1)逻辑结构:集合结构、线性结构、树形结构、图形结构

(2)物理结构:

①顺序存储结构:将数据存储在连续的存储单元里。(例如数组)
②链式存储结构:将数据存储在任意的存储单元里,通过保存地址的方式找到相关联的数据。

5.数据结构静态描述了数据元素之间的关系。高效的程序需要在数据结构的基础上设计合理的算法。

算法的概念:是特定的问题的求解步骤的描述。在计算机中表现为指令的有序序列。

6.算法的特性:(1)输入(2)输出(3)有穷性(4)确定性(5)可行性

7.程序 = 数据结构 + 算法。

8.算法的效率表示方法采用大O表示法。

概念:大O的表示法(O()),也就是查看最高次项的表示法。分析的算法的时间复杂度,指的都是算法的最坏时间复杂度。
算法的空间复杂度:
S(n) = O(f(n))

大O表示方法如下:

二、线性表的基本概念

1.定义:

(1)线性表是由0个或者多个数据元素组成的集合。
(2)线性表中数据元素之间是有顺序的。
(3)线性表中的数据元素的个数必须有限。
(4)线性表中的数据元素类型必须相同。

线性表是具有相同类型的n个数据元素的有限序列。

2.特性:

(1)第一个元素只有一个后继
(2)线性表的最后一个元素只有一个前驱
(3)除了a0和an以外其他的元素都应该既有前驱又有后继
(4)线性表能够逐项访问和顺序存取

3.线性表的相关操作:

(1)创建
(2)销毁
(3)得到长度
(4)从线性表删除一个元素
(5)从线性表添加一个元素
(6)在线性表的特定位置添加元素

三. 线性表之顺序存储结构

      下面我要实现的是线性表中的元素为整型的顺序存储结构,及它的主要运算:增删查。

先来简单的定义一下这个线性表的顺序存储结构:

#define MAXLENGTH 20

struct sequencelist
{
	int data[MAXLENGTH];
	int length;
};


其中data数组为这个线性表的主要部分,数据元素就存在于此数组中,而对这个线性表的操作都是基于这个数组。

length是这个线性表的一个属性,表示这个线性表包含元素的个数。

  增:线性表的插入操作

对线性表的插入就是对data数组的插入,然后将其length增加。

//insert opration
int insert(struct sequencelist *list,int index,int element)
{
	int length = list->length;
	if(length ==0 || index < 0 || index > length || length >= MAXLENGTH)
		return ERROR;
	list->data[index] = element;
	for(int i = length - 1;i>index;i--)
	{
		list->data[i+1] = list->data[i];
	}	
	list->length++;
	return OK;
}

删:线性表的删除操作

类似增的相反操作。

// Delete opration
int delete(struct sequencelist *list,int index)
{
	int length = list->length;
	if(length ==0 || index < 0 || index > length-1 )
		return ERROR;
	for(int i = index;i<length-1;i++)
	{
		list->data[i] = list->data[i+1];
	}
	list->data[length-1] = '\0';//delete the last element.
	list->length--;
	return OK;
}

查:线性表的取元素操作

用索引值查找元素的值。

//get list elements
//make sure elemet is NOT NULL when calling.
int getElement(struct sequencelist list,int index,int *element)
{
	printf("\ngetElement\n");
	int length = list.length;
	printf("length is %d\n",length);
	if(length ==0 || index < 0 || index >= length)
		return ERROR;
	*element = list.data[index];
	return OK;
}

从程序中可以看出增删操作的时间复杂度都是0(n),所以这两项操作都是不是它的强项。而查找操作的时间复杂度是O(1),那么线性表的顺序存储结构的优势就是可以快速的取出任意位置的元素。

上面的3种操作作为较为基本的操作,是本人的学习笔记。如果大虾们发现哪里有不妥,请不吝赐教。

而线性表的其他操作如求前驱元素、求后驱元素、判断表中是否存在某元素值、清空操作等等有意思的操作还待空闲时去完成。


较为完整的调试例子:

//201414.07
//lincoln
//linear list
//Sequence Storage Structure 
//
#include <stdio.h>

#define OK 1
#define ERROR -1
#define TURE 1
#define FALSE 0
#define MAXLENGTH 20

struct sequencelist
{
	int data[MAXLENGTH];
	int length;
};

//get list elements
//make sure elemet is NOT NULL when calling.
int getElement(struct sequencelist list,int index,int *element)
{
	printf("\ngetElement\n");
	int length = list.length;
	printf("length is %d\n",length);
	if(length ==0 || index < 0 || index >= length)
		return ERROR;
	*element = list.data[index];
	return OK;
}

//insert opration
//
int insert(struct sequencelist *list,int index,int element)
{
	printf("\ninsert\n");
	int length = list->length;
	printf("length is %d\n",length);
	if(length ==0 || index < 0 || index > length || length >= MAXLENGTH)
		return ERROR;
	list->data[index] = element;
	for(int i = length - 1;i>index;i--)
	{
		list->data[i+1] = list->data[i];
	}	
	list->length++;
	return OK;
}

// Delete opration
//
int delete(struct sequencelist *list,int index)
{
	printf("\ndelete\n");
	int length = list->length;
	printf("length is %d\n",length);
	if(length ==0 || index < 0 || index > length-1 )
		return ERROR;
	for(int i = index;i<length-1;i++)
	{
		printf("delete data[%d]\n",i);
		list->data[i] = list->data[i+1];
	}
	list->data[length-1] = '\0';//delete the last element.
	list->length--;
	return OK;
}

int main()
{
	struct sequencelist list = 
	{
		{3,1,5,7,12,78,34},
		7
	};

	printf("list length  : %d\n",list.length);
	//Test get
	int *element = 0, test = 8;
	element = &test;
	if(OK == getElement(list,2,element))
	{
		printf("list get 2 :%d\n", *element);
	}
	//Test insert
	if(OK == insert(&list,7,520))	
	{
		printf("list insert 7 ok!\n");
	}
	if(OK == getElement(list,7,element))
	{
		printf("list get 7 :%d\n", *element);
	}	
	if(OK == insert(&list,3,520))	
	{
		printf("list insert 3 ok!\n");
	}
	if(OK == getElement(list,3,element))
	{
		printf("list get 3 :%d\n", *element);
	}
	
	//Test delete
	if(OK == delete(&list,3))
	{
		printf("list delete 3 ok!\n");
	}
	if(OK == getElement(list,3,element))
	{
		printf("list get 3 :%d\n", *element);
	}
	if(OK == delete(&list,6))
	{
		printf("list delete 6 ok!\n");
	}
	if(OK == getElement(list,6,element))
	{
		printf("list get 6 :%d\n", *element);
	}
	else
	{
		printf("list get ERROR!\n");
	}
}

附:








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值