数据结构 ——顺序表【c语言版】

线性表:具有相同特性的数据元素(既同类型数据)的一个有限序列.

注:同一线性表中的元素必定具有相同特性

线性表的特性:1.有穷性 2.一致性  3.序列性

线性表的最本质特征:有唯一的前驱和后继

线性表的顺序存储结构———顺序表

顺序存储结构——逻辑上相邻的元素,在物理上也相邻

        在c语言中,顺序表通常用数组来存储,这与python中的列表不同,数组是给定长度的,数组中元素的地址也是相邻的,且数组中的元素类型一定要相同,而列表list是的长度理论上是可以无限添加的,(因为python内部已经帮我们实现了),列表中的元素类型也开始是不同的,且列表中各元素的可以是任意的。

言归正传,c语言中的顺序表采用数组来实现:

c语言顺序表的基本操作,涉及以下操作:

        1.初始化顺序表

        2.销毁:顺序存储不存在销毁操作        

        3.判断顺序表是否为空

        4.求顺序表长度

        5.输出顺序表元素

        6.取值,取出顺序表的某一个值

        7.查找,查看某一个值是否在顺序表中

        8.插入,在指定位置插入数据,后续元素向后移动,长度增加

        9.删除,删除指定位置的数据,后续元素向前移动,长度减小

        在顺序表中,为了简单,假设ElemType为int类型,还有一个length来记录顺序表的长度,SQList类型声明如下:

#define MAXSIZE 128

typedef int ElemType;

typedef struct
{
	ElemType data[MAXSIZE];//存储线性表的元素值 
	int length;//存储线性表的元素个数 
}SQList;

1)初始化顺序表

        
        初始化,构造一个空的线性表 ,代码如下:


SQList InitList()
{
	SQList l;
	l.length=0; 
	return l;
}

2) 销毁顺序表

        顺序存储不存在销毁操作 

3)判断顺序表是否为空

        若顺序表为空,返回1,否则返回0,上面SQList我们已经有了一个lenght,并且在初始化中已经将lenght赋予0,这里只需要判断lenght的值便可以确定顺序表是否为空,代码如下:

int ListEmpty(SQList l)
{
	if(l.length==0)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

4)求顺序表长度

        顺序表的长度就是lenght,代码如下:

int ListLength(SQList l)
{
	return l.length; 
}

5)输出顺序表元素

        这里只需要用一个for循环,在加以一定条件即可,代码如下:

/*
元素的下标范围:0 --  length-1 
*/
void DispList(SQList l)
{
	int i;
	printf("线性表的元素为:");
	for(i=0;i<=l.length-1;i++)
	{
		printf("%d ",l.data[i]);
	}
	printf("\n");
}

6)取值

        想要得到顺序表中的某个元素,这里需要判断顺序表是否为空、是否在顺序表的长度之类以确保参数合法性,代码如下:

/*
把线性表l中的第i个元素取出来,存储在*e中 
参数合法性:i>=1&&i<=length 

若参数合法,进行相关操作,并返回1;
否则,提示,返回0 
*/
int GetElem(SQList l,int i,ElemType *e)
{
	if(i>=1&&i<=l.length)
	{
		*e=l.data[i-1];
		return 1;
	} 
	else
	{
		printf("参数不合法!\n");
		return 0;
	}	 
} 

7)查找

        在线性表l中查找是否存在值为e的元素,若存在,返回该元素的位序(第几个);否则,返回0 ,若存在多个相同元素,只返回第一个的位序,代码如下:

int LocateElem(SQList l,ElemType e)
{
	int i;
	for(i=0;i<=l.length-1;i++)
	{
		if(l.data[i]==e)
		{
			return i+1;
		}
	}
	return 0;	 
}


8)插入元素

       在顺序表中的第i个位置,添加一个值为e的元素进去,这里需要将原来在第i个位置上的元素及其后面的元素都往后移动,还需要考虑参数i的合法性,参数合法性:i>=1&&i<=length+1 ,若参数合法,进行相关操作,并返回1;否则,提示,返回0,代码如下:

int ListInsert(SQList *l,int i,ElemType e)
{
	int j;
	
	if(i>=1&&i<=(*l).length+1)
	{
		//1.往后移动一个位置
		/*
		移动下标范围:i-1  --  length-1 
		*/
		for(j=(*l).length-1;j>=i-1;j--)
		{
			(*l).data[j+1]=(*l).data[j];
		}
		//2.把元素添加进去
		(*l).data[i-1]=e;
		//3.长度+1
		(*l).length=(*l).length+1; 
		return 1;
	}
	else
	{
		printf("参数不合法!\n");
		return 0;
	}
}

  

9)删除元素
        把顺序表的第i个元素删除,并把删除的元素值存储到*e中,这里需要考虑参数i的合法性,参数合法性:i>=1&&i<=length ,若参数合法,进行相关操作,并返回1;否则,提示,返回0  ,删除以后还需要将原来在第i+1个位置上的元素及其后面的元素都往前移动,代码如下:

/*
把线性表l的第i个元素删除,并把删除的元素值存储到*e中

参数合法性:i>=1&&i<=length 

若参数合法,进行相关操作,并返回1;
否则,提示,返回0  
*/
int ListDelete(SQList *l,int i,ElemType *e)
{
	int j;
	
	if(i>=1&&i<=(*l).length)
	{
		//1.把第i个元素值存储到*e中
		*e=(*l).data[i-1];
		//2.往前移动一个位置
		/*
		移动下标范围:i  --  length-1 
		*/ 
		for(j=i;j<=(*l).length-1;j++)
		{
			(*l).data[j-1]=(*l).data[j];
		}
		//3.长度-1
		(*l).length=(*l).length-1; 
		return 1;
	}
	else
	{
		printf("参数不合法!\n");
		return 0;
	}
}

总结:

                在顺序表中插入元素所需移动元素的平均次数为:n/2,在顺序表中删除元素所需移动元素的平均次数为(n-1)/2,因此,插入和删除元素的时间复杂度都为O(n)

最后在附上完整代码:

#include <stdio.h>
#define MAXSIZE 128

typedef int ElemType;

typedef struct
{
	ElemType data[MAXSIZE];//存储线性表的元素值 
	int length;//存储线性表的元素个数 
}SQList;

/*
1.初始化
构造一个空的线性表 
*/
SQList InitList()
{
	SQList l;
	l.length=0; 
	return l;
}

/*
2.销毁
顺序存储不存在销毁操作 
*/ 
void DestroyList(SQList *l)
{
	
}

/*
3.判断线性表是否为空
若为空,返回1;
否则,返回0 
*/
int ListEmpty(SQList l)
{
	if(l.length==0)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

/*
4.求长度 
*/
int ListLength(SQList l)
{
	return l.length; 
}

/*
5.输出
元素的下标范围:0 --  length-1 
*/
void DispList(SQList l)
{
	int i;
	printf("线性表的元素为:");
	for(i=0;i<=l.length-1;i++)
	{
		printf("%d ",l.data[i]);
	}
	printf("\n");
}

/*
6.取值 
把线性表l中的第i个元素取出来,存储在*e中 
参数合法性:i>=1&&i<=length 

若参数合法,进行相关操作,并返回1;
否则,提示,返回0 
*/
int GetElem(SQList l,int i,ElemType *e)
{
	if(i>=1&&i<=l.length)
	{
		*e=l.data[i-1];
		return 1;
	} 
	else
	{
		printf("参数不合法!\n");
		return 0;
	}	 
} 

/*
7.查找
在线性表l中查找是否存在值为e的元素,
若存在,返回该元素的位序(第几个);
否则,返回0 

备注:若存在多个相同的元素,只找第1个 
*/
int LocateElem(SQList l,ElemType e)
{
	int i;
	for(i=0;i<=l.length-1;i++)
	{
		if(l.data[i]==e)
		{
			return i+1;
		}
	}
	return 0;	 
}

/*
8.添加
在线性表l中的第i个位置,添加一个值为e的元素进去

参数合法性:i>=1&&i<=length+1 

若参数合法,进行相关操作,并返回1;
否则,提示,返回0  
*/
int ListInsert(SQList *l,int i,ElemType e)
{
	int j;
	
	if(i>=1&&i<=(*l).length+1)
	{
		//1.往后移动一个位置
		/*
		移动下标范围:i-1  --  length-1 
		*/
		for(j=(*l).length-1;j>=i-1;j--)
		{
			(*l).data[j+1]=(*l).data[j];
		}
		//2.把元素添加进去
		(*l).data[i-1]=e;
		//3.长度+1
		(*l).length=(*l).length+1; 
		return 1;
	}
	else
	{
		printf("参数不合法!\n");
		return 0;
	}
}

/*
9.删除
把线性表l的第i个元素删除,并把删除的元素值存储到*e中

参数合法性:i>=1&&i<=length 

若参数合法,进行相关操作,并返回1;
否则,提示,返回0  
*/
int ListDelete(SQList *l,int i,ElemType *e)
{
	int j;
	
	if(i>=1&&i<=(*l).length)
	{
		//1.把第i个元素值存储到*e中
		*e=(*l).data[i-1];
		//2.往前移动一个位置
		/*
		移动下标范围:i  --  length-1 
		*/ 
		for(j=i;j<=(*l).length-1;j++)
		{
			(*l).data[j-1]=(*l).data[j];
		}
		//3.长度-1
		(*l).length=(*l).length-1; 
		return 1;
	}
	else
	{
		printf("参数不合法!\n");
		return 0;
	}
}


int main()
{
	SQList InitList();
	void DestroyList(SQList *l);
	int ListEmpty(SQList l);
	int ListLength(SQList l);
	void DispList(SQList l);
	int GetElem(SQList l,int i,ElemType *e);
	int LocateElem(SQList l,ElemType e);
	int ListInsert(SQList *l,int i,ElemType e);
	int ListDelete(SQList *l,int i,ElemType *e);
	
	//在使用之前,一定要初始化
	SQList ll;
    ll=InitList();
    ListInsert(&ll,ListLength(ll)+1,100);
    ListInsert(&ll,ListLength(ll)+1,200);
    ListInsert(&ll,ListLength(ll)+1,300);
    ListInsert(&ll,ListLength(ll)+1,400);
    ListInsert(&ll,ListLength(ll)+1,500);
    DispList(ll);

	return 1;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值