顺序链表的操作

/*线性表的顺序存储:顺序表*/
#include <stdio.h>
#include <stdlib.h> 	//malloc

#if 0
void *malloc(size_t size);	 
功能:在堆区开辟空间
参数:size开辟空间的大小
返回:返回堆区的首地址,需要强制类型转换
#endif

#define N 10

//存储的数据类型
typedef int data_t;
//顺序表的类型
typedef struct {
	data_t a[N]; 		//实现顺序存储
	int last; 			//记录最后一个元素的下标
}sqlist_t; 				//类型名

//开辟空的顺序表
sqlist_t *sqlist_create()
{
	sqlist_t *p = NULL; 						//防止野指针的形成
	p = (sqlist_t *)malloc(sizeof(sqlist_t)); 	//开辟顺序表的空间
	if(p == NULL)
        return NULL;
        
	p->last = -1; 								//下标开始为-1

	return p; 									//将顺序表的首地址返回
}

//判断是否为满
//为满返回1,不满返回0
int sqlist_is_full(sqlist_t *p)
{
    if(p != NULL)
    	return p->last == N-1 ? 1 : 0;

#if 0
	if(p->last == N-1)
	{
		return 1;
	}
	else
	{
		return 0;
	}
#endif
}

//判断是否为空
//为空返回1,非空返回0
int sqlist_is_empty(sqlist_t *p)
{
    if(p != NULL)
        return p->last == -1 ? 1 : 0;
}

//增:从后面插入数据
int sqlist_insert(sqlist_t *p, data_t value)
{
    if(p == NULL)
        return -1;
    
	if(sqlist_is_full(p))
	{
		printf("full\n");
		return -1; 				//异常结束
	}
	p->last++;
	p->a[p->last] = value;

	return 0; 					//正常结束
}

//删:从后面删除数据
int sqlist_delete(sqlist_t *p)
{
    if(p == NULL)
        return -1;
    
	if(sqlist_is_empty(p))
	{
		printf("empty\n");
		return -1;
	}

	p->last--;
    
	return 0;
}

//改:将旧数据改成新数据
int sqlist_change(sqlist_t *p, data_t old, data_t new)
{
	int i;
    if(p == NULL)
        return -1;
    
	for(i=0; i<=p->last; i++) 	//循环整个顺序表
	{
		if(p->a[i] == old) 		//查找旧的数据
		{
			p->a[i] = new; 		//覆盖为新的数据
		}
	}

	return 0;
}

//增:按位置插入
int sqlist_insert_pos(sqlist_t *p, int pos, data_t value)
{
    if(p == NULL)
        return -1;
    
	if(sqlist_is_full(p))
	{
		printf("full\n");
		return -1;
	}

	//判断pos的有效取值区间
	if(pos < 0 || p->last + 1 < pos)
	{
		printf("pos error\n");
		return -1;
	}
	
	int i;
	for(i=p->last; i>= pos; i--)  		//移动的数据范围last ~ pos
	{
		p->a[i+1] = p->a[i]; 			//将数据向后移动
	}
	p->a[pos] = value; 					//将数据存储到pos位置
	p->last++; 							//last始终代表最后一个元素的位置

	return 0;
}

//删:按位置删除
int sqlist_delete_pos(sqlist_t *p, int pos)
{
    if(p == NULL)
        return -1;
    
	if(sqlist_is_empty(p))
	{
		printf("empty\n");
		return -1;
	}

	if(pos < 0 || p->last < pos) 		//判断pos的有效取值区间
	{
		printf("pos error\n");
		return -1;
	}

	int i;
	for(i=pos+1; i<=p->last; i++) 		//移动的数据范围pos+1 ~ last
	{
		p->a[i-1] = p->a[i]; 			//将数据向前移动
	}
	p->last--;

	return 0;
}

//删除重复
int sqlist_delete_repeat(sqlist_t *p)
{
	int i,j;
    if(p == NULL)
        return -1;
    
	for(i=0; i<p->last; i++) 			//基准值的取值范围
	{
		for(j=i+1; j<=p->last; j++) 	//与基准值比较的数据范围
		{
			if(p->a[i] == p->a[j]) 		//判断是否重复
			{ 
				sqlist_delete_pos(p,j); //按位置删除后面的数据
				j--; 					//重复判断删除后的新数据
			}
		}
	}

	return 0;
}

//遍历顺序表
int sqlist_show(sqlist_t *p)
{
	int i;
    if(p == NULL)
        return -1;
    
	for(i=0; i<=p->last; i++)
	{
		printf("%d  ",p->a[i]); 	//打印a[0] ~ a[last]
	}
	putchar('\n'); 					//输出换行符
}

int main(int argc, const char *argv[])
{
	sqlist_t *l = sqlist_create();
    if(l == NULL)
        return -1;
    
	sqlist_insert(l,10);
	sqlist_insert(l,20);
	sqlist_insert(l,30);
	sqlist_insert(l,40);
	sqlist_insert(l,50);
	printf("insert data:");
	sqlist_show(l);
	
	sqlist_delete(l);
	printf("delete data:");
	sqlist_show(l);

	sqlist_change(l,20,12);
	printf("change data:");
	sqlist_show(l);

	sqlist_insert_pos(l, 3, 15);
	printf("insert pos:");
	sqlist_show(l);

	sqlist_delete_pos(l, 3);
	printf("delete pos:");
	sqlist_show(l);
	free(l);

	putchar('\n');
	sqlist_t *w = sqlist_create();
	sqlist_insert(w,11);
	sqlist_insert(w,12);
	sqlist_insert(w,13);
	sqlist_insert(w,11);
	sqlist_insert(w,11);
	sqlist_insert(w,15);
	sqlist_insert(w,11);
	sqlist_insert(w,16);
	sqlist_insert(w,17);
	printf("insert data:");
	sqlist_show(w);

	sqlist_delete_repeat(w);
	printf("delete repeat:");
	sqlist_show(w);
	free(w);

	return 0;
}


测试结果

在这里插入图片描述

任何函数的返回值都需要做判断,提高程序的健壮性!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值