一、表
数据逻辑组织为表形式,逻辑上数据是连续排列的,每个节点(除头尾外),都有且仅有一个 前驱和一个后继,其中:
头节点 :只有后继,没有前驱
尾节点 :只有前驱,没有后继
节点: 数据逻辑的最小单元 。
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;
}