基于C语言对数据结构中线性结构三种存储方式的认知

数据结构是每一个码农都必须要熟悉的一门课程、又或者说是一种手段。每一个程序员应该都知道一句“圣经”:
        程序 = 数据结构 + 算法;

所以,我会在这篇博客记录我学习线性结构的理解和深入思考的想法。

一、线性表

        1.1顺序表的定义 

typedef int data_t;
#define N 128

typedef struct 
{
	data_t data[N];//顺序表的长度
	int last;//方便知道顺序表的下表
}sqlist,*sqlink;

sqlink list_create();//顺序表的创造
int list_clear(sqlink L);//顺序表的清除
int list_empty(sqlink L);//判断顺序表是否为空链表
int list_length(sqlink L);//求顺序表长度
int list_locate(sqlink L,data_t value);//查找元素
int list_insert(sqlink L,data_t value,int pos);//插入元素
int list_show(sqlink L);//遍历元素
int list_delete(sqlink L,int pos);//删除元素
int list_merge(sqlink L1,sqlink L2);//合并顺序表
int list_purge(sqlink L); //删除顺序表中重复的元素

在这个顺序表的定义中、建议使用typedef来定义要输入顺序表里面元素的数据类型和使用宏定义来定义数组的长度,这样有利于顺序表的重复利用和修改。 

        1.2顺序表的特点:

  1. 随机访问 ,可以在O(1)时间内找到第i个元素。
  2. 存储密度高,每个节点只存储数据元素。
  3. 拓展容量不方便。
  4. 要求系统提供一大片连续的存储空间。
  5. 插入、删除操作不方便,需要移动大量元素。

         1.3顺序表的实现:

#include<stdio.h>
#include"sqlist.h"
#include<stdlib.h>//malloc函数的库
#include<string.h>//memset函数的库

sqlink list_create()
{
	sqlink L;//struct * L 定义了一个结构体指针L

	L =(sqlink)malloc(sizeof(sqlist));//给L分配动态内存

	if(L == NULL){
		printf("list create failed\n");
		return L;
	}//判断L内存有没有分配成功

	//初始化顺序表
	memset(L,0,sizeof(sqlist));//将L内的数据全部清零
	L->last = -1;//将L下标设置为-1

	return L;

}
/*
	@ret  0 -- success  -1 -- failed
*/
int list_clear(sqlink L)
{
	if(L == NULL){
		printf("list is NULL\n");
		return -1;
	}
	
	memset(L,0,sizeof(sqlist));
	L->last = -1;
	
	return 0;
}

/*
	list_insert(L,10,0);
	list_empty: check list is empty?
	@param : list
	@ret   0 -- not empty   1 -- empty
*/
int list_empty(sqlink L)
{
	if(L->last == -1)//如果下标为1,则表示顺序表里面没有元素,即为空表
		return 1;
	else
		return 0;//也可以这么写 return(L->last == -1? 1 : 0);
}

/*
	@ret  -1 -- list is NULL   
*/
int list_length(sqlink L)    
{
	if(L == NULL)
		return -1;
	
	return (L->last+1);
}
/*
 *@ret  -1 -- not   pos -- yes  
 */
int list_locate(sqlink L,data_t value)  
{
	int i;
	for(i = 0;i <= L->last;i++){
		if(L->data[i] == value)
			return i;
	}//遍历所有元素,判断有无相等,有则输出该元素的下标
	return -1;
}
int list_insert(sqlink L,data_t value,int pos)
{	
	int i;
	if(L->last == N-1){
		printf("list is full\n");
		return -1;
	}//如果数组已经满表,则不能再添加元素

	if(pos<0 || pos>L->last+1){
		printf("pos is error\n");
		return -1;
	}//如果输入想要插入元素的位置小于0或者大于已有元素最大的下标,则不能插入

	for(i = L->last;i >= pos;i--){
		L->data[i+1] = L->data[i];
	}/*插入该位置时,之后的所有元素都得往后移动。且必须尾部元素先移动,保证下一个位置不会有元素,从而导致覆盖了下一个元素*/

	L->data[pos] = value;//将值赋值给要插入位置
	L->last++;//下标加一,表示元素加一			
	return 0;
}
int list_show(sqlink L){
	int i;
    //正常的入口参数检查
	if(L == NULL)
		return -1;
    //如果为空表则没必要遍历显示
	if(L->last == -1){
		printf("list is NULL\n");
	}
    
	for(i=0;i<=L->last;i++){
		printf("L->data[%d]=%d ",i,L->data[i]);
		printf("\n");
	}
	return 0;
}

int list_delete(sqlink L,int pos)
{
	int i;
    //如果为空表,则不能删除元素
	if(L->last == -1){
		printf("list is empty\n");
		return -1;
	}
    //如果要删除的位置小于0或者删除的位置大于已有元素的最大位置
	if(pos < 0 || pos > L->last){
		printf("pos is ERROR\n");
		return -1;
	}
    //删除元素和增加元素恰好相反,只需要保证没有元素覆盖即可
	for(i=pos+1;i<=L->last;i++){
		L->data[i-1]=L->data[i];
	}
	L->last--;
	return 0;	
}

        1.4顺序表的复杂实现:

int list_merge(sqlink L1,sqlink L2)//合并两个顺序表
//思路:将一个顺序表中的所有元素拿出来和另一个对比,如果不相同则插入
{
	int i = 0;
	int ret;
	while(i <= L2->last){
		ret = list_locate(L1,L2->data[i]);
//将L2的元素放入L1中查找,将返回值赋给ret。前面代码已写,返回值为-1则没有该元素,即L1中没有该元素
		if(ret == -1)
  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

godfatherlzq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值