文章目录
- 数据结构——顺序表使用
- 一、数据的逻辑结构
- 线性结构
- 非线性结构
- 二、数据存储结构
- 三、顺序表使用
- 结构体定义
- 静态顺序表
- 动态顺序表
- 顺序表功能实现代码
- 1. 创建顺序表
- 2. 清空表
- 3. 释放内存
- 4. 判断空表
- 5. 求线性表长度
- 6. 表中找数
- 7. 插入数据
- 8. 删除数据
- 9. 删除重复数据
- 10. 合并线性表
- 打印线性表
- 四、完整代码
数据结构——顺序表使用
本文学习使用数据结构中最简单的一种表顺序表,顺序表是顺序存储,属于线性表的一种。
一、数据的逻辑结构
线性结构
- 线性表
- 栈
- 队
非线性结构
- 树形结构
- 图形结构
二、数据存储结构
- 顺序存储
- 链式存储
- 索引存储
- 散列存储
三、顺序表使用
结构体定义
使用结构体定义的方法定义一个顺序表,顺序表又分为静态顺序表和动态顺序表。两种表对比,静态的是给定长度的表,很浪费空间,而动态的更加灵活一些。
静态顺序表
typedef int data_t; //灵活性:结构体中用data_t定义,如需修改数据类型只用修改这里
#define N 128
typedef struct sqlist{ //数据结构定义
data_t data[N];
int last;
}sqlist ,*sqlink;
动态顺序表
typedef int data_t; //灵活性:结构体中用data_t定义,如需修改数据类型只用修改这里
typedef struct sqlist{ //数据结构定义
data_t *data;//定义数组指针
int last;//记录当前顺序表长度
int max;//顺序表最大存储个数
}sqlist ,*sqlink;
顺序表功能实现代码
1. 创建顺序表
使用malloc函数需要对其强制转化成给定的sqlink指针类型,malloc开辟空间成功返回指向被分配内存的指针,否则返回空指针NULL。
使用malloc函数需要调用<stdlib.h>头文件,malloc开辟空间之后使用完成一定要使用free()函数释放空间,以免造成内存泄漏。
memset()函数需要调用<string.h>头文件,起到赋初值初始化的作用
sqlink list_create(){//创建顺序表
sqlink L;
L=(sqlink)malloc(sizeof(sqlist));//申请内存
if (L==NULL){
printf("list malloc failed\n");
return L;
}
//初始化
memset(L,0,sizeof(sqlist));
L->last=-1;
return L;
}
2. 清空表
/*
**清空表:0代表成功,-1代表失败
*/
int list_clear(sqlink L){
if (L==NULL)
return -1;
//释放内存 last=-1代表空表
memset(L,0,sizeof(sqlist));
L->last=-1;
return 0;
}
3. 释放内存
防止造成内存泄露
/*
**内存释放
*/
int list_free(sqlink L){
if(L=NULL)
return -1;
free(L);
L=NULL;
return 0;
}
4. 判断空表
/*
**判断表是否为空表
**1代表空表 0代表非空表
*/
int list_empty(sqlink L){
if(L->last==-1)
return 1;
else
return 0;
}
5. 求线性表长度
/*
**求线性表长度
*/
int list_length(sqlink L){
if(L==NULL)
return -1;
return (L->last+1);
}
6. 表中找数
/*
**判断一个数在不在线性表中,若存在给出位置
*/
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;
}
7. 插入数据
/*
**向线性表插入数据
*/
int list_insert(sqlink L,int value,data_t 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 invalid\n");
return -1;
}
//移动线性表 所插入位置及后面的源数据都往后移动,首先从末位移动
for(i=L->last;i>=pos;i--){
L->data[i+1]=L->data[i];
}
//更新插入位置数据
L->data[pos]=value;
L->last++;
}
8. 删除数据
/*
**删除线性表某个位置的数
*/
int list_delete(sqlink L,int pos)
{
int i;
//检查是否为空表
if(L->last==-1){
printf("list is empty\n");
return -1;
}
//检查位置合法性
if(pos<0||pos>L->last+1){
printf("pos is invalid\n");
return -1;
}
//移动线性表 删除后面位置上的数都要向前移动,首先是删除后一个位置开始移动
for(i=pos+1;i<=L->last;i++)
L->data[i-1]=L->data[i];
//更新表长度last
L->last--;
return 0;
}
9. 删除重复数据
/*
**删除线性表重复的元素
*/
int list_purge(sqlink L){
int i,j;
if(L->last==0)
return 0;
i=1;
while(i<=L->last){
j=i-1;
while(j>=0){
if(L->data[i]==L->data[j]){
list_delete(L,i);
break;
}
else j--;
}
i++;
}
}
10. 合并线性表
/*
**线性表合并
*/
int list_merge(sqlink L1,sqlink L2){
int i=0,ret;
while(i<=L2->last){
ret=list_locate(L1,L2->data[i]);
if(ret==-1){
if(list_insert(L1,L2->data[i],L1->last+1)==-1)
return -1;
}
i++;
}
}
打印线性表
/*
**打印线性表
*/
int list_show(sqlink L){
if(L==NULL)
return -1;
if(L->last==-1)
printf("list is empty\n");
for(int i=0;i<=L->last;i++)
{
printf("%d ",L->data[i]);
}
printf("\n");
}
四、完整代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef int data_t; //灵活性:结构体中用data_t定义,如需修改数据类型只用修改这里
#define N 128
typedef struct sqlist{ //数据结构定义
data_t data[N];
int last;
}sqlist ,*sqlink;
sqlink list_create(){//创建顺序表
sqlink L;
L=(sqlink)malloc(sizeof(sqlist));
if (L==NULL){
printf("list malloc failed\n");
return L;
}
//初始化
memset(L,0,sizeof(sqlist));
L->last=-1;
return L;
}
/*
**清空表:0代表成功,-1代表失败
*/
int list_clear(sqlink L){
if (L==NULL)
return -1;
//释放内存 last=-1代表空表
memset(L,0,sizeof(sqlist));
L->last=-1;
return 0;
}
/*
**内存释放
*/
int list_free(sqlink L){
if(L=NULL)
return -1;
free(L);
L=NULL;
return 0;
}
/*
**判断表是否为空表
**1代表空表 0代表非空表
*/
int list_empty(sqlink L){
if(L->last==-1)
return 1;
else
return 0;
}
/*
**求线性表长度
*/
int list_length(sqlink L){
if(L==NULL)
return -1;
return (L->last+1);
}
/*
**判断一个数在不在线性表中,若存在给出位置
*/
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,int value,data_t 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 invalid\n");
return -1;
}
//移动线性表 所插入位置及后面的源数据都往后移动,首先从末位移动
for(i=L->last;i>=pos;i--){
L->data[i+1]=L->data[i];
}
//更新插入位置数据
L->data[pos]=value;
L->last++;
}
/*
**删除线性表某个位置的数
*/
int list_delete(sqlink L,int pos)
{
int i;
//检查是否为空表
if(L->last==-1){
printf("list is empty\n");
return -1;
}
//检查位置合法性
if(pos<0||pos>L->last+1){
printf("pos is invalid\n");
return -1;
}
//移动线性表 删除后面位置上的数都要向前移动,首先是删除后一个位置开始移动
for(i=pos+1;i<=L->last;i++)
L->data[i-1]=L->data[i];
//更新表长度last
L->last--;
return 0;
}
/*
**删除线性表重复的元素
*/
int list_purge(sqlink L){
int i,j;
if(L->last==0)
return 0;
i=1;
while(i<=L->last){
j=i-1;
while(j>=0){
if(L->data[i]==L->data[j]){
list_delete(L,i);
break;
}
else j--;
}
i++;
}
}
/*
**线性表合并
*/
int list_merge(sqlink L1,sqlink L2){
int i=0,ret;
while(i<=L2->last){
ret=list_locate(L1,L2->data[i]);
if(ret==-1){
if(list_insert(L1,L2->data[i],L1->last+1)==-1)
return -1;
}
i++;
}
}
/*
**打印线性表
*/
int list_show(sqlink L){
if(L==NULL)
return -1;
if(L->last==-1)
printf("list is empty\n");
for(int i=0;i<=L->last;i++)
{
printf("%d ",L->data[i]);
}
printf("\n");
}
/*
**测试代码
*/
void test_insert()
{
sqlink L;
L=list_create();
if(L==NULL)
return ;
list_insert(L,10,0);
list_insert(L,20,0);
list_insert(L,30,0);
list_insert(L,40,0);
list_insert(L,50,0);
list_show(L);
list_insert(L,200,list_length(L));
list_show(L);
list_free(L);
}
void test_delete(){
sqlink L;
L=list_create();
list_insert(L,10,0);
list_insert(L,20,1);
list_insert(L,30,2);
list_insert(L,40,3);
list_insert(L,50,4);
list_delete(L,1);
list_show(L);
list_free(L);
}
void test_merge(){
sqlink L1,L2;
L1=list_create();L2=list_create();
list_insert(L1,10,0);
list_insert(L1,20,0);
list_insert(L1,30,0);
list_insert(L1,40,0);
list_insert(L2,20,0);
list_insert(L2,50,0);
list_insert(L2,70,0);
list_insert(L2,40,0);
list_show(L1);list_show(L2);
puts("*********");
list_merge(L1,L2);
list_show(L1);list_show(L2);
list_free(L1); list_free(L2);
}
void test_purge()
{
sqlink L;
L=list_create();
list_insert(L,10,0);
list_insert(L,10,1);
list_insert(L,30,2);
list_insert(L,10,3);
list_insert(L,50,4);
list_insert(L,30,5);
list_show(L);
list_purge(L);
list_show(L);
list_free(L);
}
int main()
{
test_purge();
return 0;
}