表基本操作——增删改查

一、表


        数据逻辑组织为表形式,逻辑上数据是连续排列的,每个节点(除头尾外),都有且仅有一个 前驱和一个后继,其中:

        头节点 :只有后继,没有前驱 
        尾节点 :只有前驱,没有后继 
    

节点: 数据逻辑的最小单元 。 
C语言中数组就是表结构。 
    

二、表的存储结构

        表的存储有两种方式:顺序存储(连续存储)、离散存储。
        顺序存储:  数组存储  
            顺序表 :存储上连续存储,逻辑上是表结构 
        离散存储:  链式存储  
            链表:   存储上使用离散存储, 逻辑上是表结构 

三、顺序表的基本概念

概念:用一组地址连续的存储单元依次存储线性表的数据元素,这种存储结构的线性表称为顺序表。

特点:逻辑上相邻的数据元素,物理次序也是相邻的。

四、建立一个顺序表的基本步骤

        1、定义顺序表

        顺序表中需要定义三个内容,即该顺序表的最大存储长度、当前存储长度以及存储的数据。

#include<stdio.h>
#include<stdlib.h>
//顺序表
//定义数据类型
typedef int Data_t;
//第一步:定义表
struct list_t
{
	int max_len;  //存储的最大长度
	int cnt;      //当前长度
	Data_t *data; 
};

         2、顺序表的创建

//第二步:创建表
int create_list(struct list_t *head,int max_len)
{
	//入参检查
	if(head == NULL || max_len == 0)
	  return -1;  //返回错误码
	//填充参数
	head->max_len=max_len;
	head->cnt=0;
	//申请堆区内存空间
	head->data= (Data_t *)malloc(max_len * sizeof(Data_t));
	if(head->data == NULL)
	{
		printf("错误!");
		return -2;
	}
	return 0;
}

        3、顺序表的插入

//向表中插入元素
int insert_list(struct list_t *head,int index,Data_t data)
{
	//入参检查
	if(head == NULL || head->data == NULL) return -1;
	//判断位置是否可以插入
	if(index > head->cnt)
	{
		printf("插入的位置%d不存在!\n",index);
		return -2;
	}
	//判断顺序表是否已满
	if(head->cnt==head->max_len)
	{
		printf("顺序表已满!\n");
		return -3;
	}
	//移开位置,找到最个一个元素的下标
	for(int i=head->cnt-1; i>=index; i--)
	{
		head->data[i+1] = head->data[i];
	}
	head->data[index]=data;
	head->cnt ++;//更新元素个数
	return 0;
}

4、顺序表的遍历

//遍历表
int show_list(struct list_t *head)
{
	if(head == NULL || head->data == NULL) return -1;
	for(int i=0; i<head->cnt ;i++)
		printf("%d ",head->data[i]);
	printf("\n");
	return 0;
}

5、顺序表的删除

①、删除整个顺序表

//删除表
int del_list(struct list_t *head)
{
	if(head == NULL) return -1;
	if(head->data)
		free(head->data);
	head->data = NULL;
	head->cnt = 0;
	head->max_len = 0;
	return 0;
}

②、给定下标,删除顺序表中的元素

//删除表中的某一个元素
int del_list_data(struct list_t *head,int index)
{
	//入参检查
	if(head == NULL || head->data == NULL) return -1;
	//判断表是否为空
	if(head->cnt == 0)
	{
		printf("该顺序表为空!\n");
		return -2;
	}
	//判断插入位置下标是否合法
	if(index >= head->cnt)
	{
		printf("输入位置下标不合法!\n");
		return -3;
	}
	//找到位置下表  
	//删除元素之后,将后面的元素依次往前移动
	for(int i=index; i<= head->cnt-1-index; i++)
	{
		head->data[i]=head->data[i+1];
	}
	head->cnt --;
	return 0;
}

6、顺序表的修改



//修改表中的某一个元素
int change_list_data(struct list_t *head,int index,Data_t data)
{
	//入参检查
	if(head == NULL || head->data == NULL) return -1;
	//判断表是否为空
	if(head->cnt == 0)
	{
		printf("该表为空!\n");
		return -2;
	}
	//判断位置下表是否合法
	if(index >= head->cnt)
	{
		printf("输入位置不合法!\n");
		return -3;
	}
	//找到位置,替换数据
	head->data[index] = data;
	return 0;
}

7、顺序表的查找

①、根据下标查找元素


//根据元素下标查找表中的元素
int find_list_data(struct list_t *head,int index)
{
	//入参检查
	if(head == NULL || head->data ==NULL) return -1;
	//判断表是否为空
	if(head->cnt == 0)
	{
		printf("该顺序表为空!\n");
		return -2;
	}
	//判断下标是否存在
	if(index >= head->cnt)
	{
		printf("下标不存在!\n");
		return -3;
	}
	printf("下标%d处的元素是%d\n",index,head->data[index]);
	return 0;
}


②、根据元素值查找下标

//根据元素的值 得到下标  找第一个值
int get_list_index(struct list_t *head, int *index, Data_t data)
{
	if(head == NULL || head->data == NULL) return -1;
	for(int i=0; i<head->cnt; i++)
	{//找到值相同的下标 
		if(head->data[i] == data) 
		{
			*index = i;
			return 0;
		}
	}
}

8、获取顺序表长度

//获取某个下标的元素值
int get_list_data(struct list_t *head, int index, Data_t *data)
{
	if(head == NULL || head->data == NULL) return -1;
	//下标不存在
	if(index >= head->cnt) 
	{
		printf("%d号元素不存在!\n",index);
		return -2;
	}
	*data = head->data[index];
	return 0;
}

9、顺序表的判空判满

//判断空
//返回值 <0 err  ==0 空的 >0 表中存放的数据个数
int is_empty(struct list_t *head)
{
	if(head == NULL || head->data == NULL) return -1;
	return head->cnt;
}

//判断满
//返回值 <0 err ==0 满  >0 表示表中还可以存放多少个元素
int is_full(struct list_t *head)
{
	if(head == NULL || head->data == NULL) return -1;
	return head->max_len - head->cnt;
}

10、顺序表的合并

//合并两个表
//L1 = L1 + L2
int connect_list(struct list_t *L1, struct list_t *L2)
{
	if(L1 == NULL || L2 == NULL || L1->data == NULL || L2->data == NULL)
	  return -1;
	if(L1->max_len - L1->cnt  < L2->cnt  )
	{
		printf("L1长度不足!\n");
		return -2;
	}
	//复制L2中所有节点到L1中
	for(int i=0;i< L2->cnt; i++) 
	  L1->data[L1->cnt + i] = L2->data[i];
	L1->cnt += L2->cnt;
	return 0;
}

五、顺序表的调用

int main()
{
	//使用表结构 创建一个表
	struct list_t L , L2;
	//要求创建一个有25个元素空间的顺序表
	int ret = create_list(&L, 25);
	if(ret == 0)
	{
		printf("表L创建成功!!\n");
		printf("data=%p\n",L.data);
	}
	ret = create_list(&L2, 25);
	if(ret == 0)
	{
		printf("表L2创建成功!!\n");
		printf("data=%p\n",L2.data);
	}

	insert_list(&L, 0, 10);
	insert_list(&L, 0, 20);
	insert_list(&L, 0, 30);
	insert_list(&L, 0, 40);
	show_list(&L);
	//尾巴插入
	for(int i=100; i<110; i++)
		insert_list(&L2, is_empty(&L2) , i);
	show_list(&L2);
	//合并
	connect_list(&L,&L2);
	show_list(&L);


	//获得表中的一个元素
	Data_t dt;
	if ( get_list_data(&L, 3, &dt) == 0 )
	{
		printf("3号元素的值为%d\n",dt);
	}
	int index;
	if( get_list_index(&L, &index, 20 ) == 0)
	{
		printf("元素值为20的下标是%d\n",index);
	}

	//删除表
	del_list(&L);

	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值