文章目录

  • 数据结构——顺序表使用
  • 一、数据的逻辑结构
  • 线性结构
  • 非线性结构
  • 二、数据存储结构
  • 三、顺序表使用
  • 结构体定义
  • 静态顺序表
  • 动态顺序表
  • 顺序表功能实现代码
  • 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;
 }