原理是申请一段连续的内存空间,对这段内存空间进行相关操作实现基本的功能,大致实现了数据结构C语言版第二章顺序线性表的所有功能和算法,代码如下
#include"stdio.h"
#include"stdlib.h"
#define OVERFLOW 0
#define OK 1
#define LIST_INIT_SIZE 20
#define LISTINCREMENY 3
#define TRUE 1
#define FALSE 0
/*
结构体的定义如下,在该结构体中,有三个属性
指针变量elem用来存储数据,为一片连续空间的开始地址
length为当前长度,也就是存储元素的个数
LIST_INIT_SIZE为初始化申请的长度,也就是
该线性表开始时能存储的最大容量
*/
typedef int Status;
typedef struct{
int *elem;//连续空间基地址,存储数据
int length;//记录长度
int listsize;//记录初始化线性表大小
int exist;//判断符号表状态,申请成功赋值为1
}Sqlist;//将该结构体定义为Sqlist
//定义全局变量listsizeChange,记录线性表大小变化过程,开始值为初始化大小
int LISTSIZE_CHANGE = LIST_INIT_SIZE;
/*
线性表初始化函数,申请一片连续的空间存储数据
初始化线性表大小和当前容量
*/
int InitList(Sqlist *L){
(*L).elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));//动态申请五个Int型大小的元素,用来存储数据,开始地址赋值给*L.elem
if(!(*L).elem){//申请失败则返回FALSE
return FALSE;
}
(*L).length = 0;//初始化时没有存储任何元素,线性表的长度为0
(*L).listsize = LIST_INIT_SIZE;//申请的最大容量为当前长度
(*L).exist = 1;
return TRUE;
}
/*
销毁线性表,释放所申请的地址空间
*/
int DestroyList(Sqlist *L){
free((*L).elem);//释放所申请的固定大小的内存空间
(*L).elem = NULL;
(*L).length = 0;
(*L).listsize = 0;
return 0;
}
/*
在结构体中插入数据,参数有结构体名,下标,插入元素
下标从0开始
版本一: 有限插入,线性表初始容量和可扩展容量都已经限定,不能超过给定的容量
*/
int InsertLIst(Sqlist *L, int i, int e){
if((*L).exist == 1 && i >= 0 && i < LISTINCREMENY + LIST_INIT_SIZE){//当前大小空间等于全局变量大小,下标取值符合范围
int *p, *q;//申请两个指针变量
int *newbase;
//新地址的开辟,只开辟一次, 当当前容量比最大容量大的时候开始开辟
if((*L).length >= (*L).listsize){//当赋值下标超过了初始化分配的内存大小为,进行内存的扩张
newbase = (int *)realloc((*L).elem, (LISTINCREMENY + LIST_INIT_SIZE)*sizeof(int));//重新分配内存,参数一为旧内存内容,参数而为新内存大小
if(!newbase){
printf("内存扩张失败");
return FALSE;
}
(*L).elem = newbase;//将新分配的地址赋值给elem
(*L).listsize = LISTINCREMENY + LIST_INIT_SIZE;
}
//插入算法
q = (*L).elem + i;//q为要插入的地址位置,(*L).elem为初始地址加上地址偏移位数i就为要插入的初始地址
//插入的算法为,把插入前的位置不变,当前位置和后面位置依次加一后移
for(p = (*L).elem + (*L).length; p >= q; p --){//p为尾地址,将尾地址内存中数据后移一位
*(p + 1) = *p;
}
*q = e;//将要插入的内存进行赋值
(*L).length ++;
return 1;
}
else{
printf("下标越界\n");
return FALSE;
}
}
//线性表的遍历,打印输出每一个元素
int TraverseList(Sqlist *L){
int *begin;
begin = (*L).elem;
for(begin = (*L).elem; begin <(*L).elem + (*L).length; begin ++){
printf("%d\n", *begin);
}
return 0;
}
//将线性表置为空表,空表的条件就是长度为0
int ClearList(Sqlist *L){
(*L).length = 0;
return TRUE;
}
//判断是否为空表,如果为空返回true,否则返回false
int IsemptyList(Sqlist *L){
if((*L).length == 0){
return TRUE;
}
else{
return FALSE;
}
}
//获取线性表元素的个数,返回元素个数
int ListLength(Sqlist *L){
return (*L).length;
}
//获取指定下标位置的元素
int GetElem(Sqlist *L, int i){
if(i >=0 && i < (*L).length){
return *((*L).elem + i);//返回特定内存位置的地址
}
return FALSE;
}
//返回第一个满足与元素e相等的下标,不存在则返回-1
int LocateElem(Sqlist *L, int e){
int i = 0;
int flag = 0;
int *p;
for(p = (*L).elem; p < (*L).elem + (*L).length; p ++){
if(*p == e){
flag ++;
break;
}
i ++;
}
if(flag != 0){
return i;
}
return -1;
}
//获取前驱元素
int PriorElem(Sqlist *L, int cur){
int locate = LocateElem(L, cur);
if(locate > 0 && locate < (*L).length){
return *((*L).elem + locate - 1);
}
else{
return -1;
}
// return locate;
}
//获取后继元素
int NextElem(Sqlist *L, int cur){
int locate = LocateElem(L, cur);
if(locate >= 0 && locate < (*L).length - 1){
return *((*L).elem + locate + 1);
}
else{
return -1;
}
}
//删除指定下标位置的元素
int DeleteList(Sqlist *L, int i){
int *p, *q;//p为要删除位置的地址,q为地址尾部
for(p = (*L).elem + i; p < (*L).elem + (*L).length; p ++){
*p = *(p + 1);
}
(*L).length --;
return 1;
}
//对两个线性表进行集合操作,A = A并B,对两个集合进行并,操作,最后结果赋值给A
void UnionList(Sqlist *La, Sqlist *Lb){
int LengthA = ListLength(La);
int LengthB = ListLength(Lb);
int i = 0;
for(i = 0; i < LengthB; i ++){
if(LocateElem(La, (GetElem(Lb, i))) == -1){//如果该元素在La中不存在
InsertLIst(La, LengthA, GetElem(Lb, i));
LengthA ++;
}
}
}
//对两个有序线性表按照输出重新加入到一个新的线性表中 L = LA 并 LB
void MergeList(Sqlist *L, Sqlist *La, Sqlist *Lb){
//(*L).length = (*La).length + (*Lb).length;
int LengthA = ListLength(La);
int LengthB = ListLength(Lb);
int i = 0;
int j = 0;
int k = 0;
while((i < LengthA) && (j < LengthB)){
if(GetElem(La, i) <= GetElem(Lb, j)){
InsertLIst(L, k, GetElem(La, i));
k ++;
i ++;
}
else{
InsertLIst(L, k, GetElem(Lb, j));
k ++;
j ++;
}
}
while(i < LengthA){
InsertLIst(L, k, GetElem(La, i));
i ++;
}
while(j < LengthB){
InsertLIst(L, k, GetElem(Lb, j));
j ++;
}
}
int main(){
Sqlist L;//定义一个结构体L
InitList(&L);//将初始化的结构体进行初始化,参数为该结构体的基地址
Sqlist Lb;
InitList(&Lb);
InsertLIst(&Lb, 0, 1);
InsertLIst(&Lb, 1, 11);
InsertLIst(&Lb, 2, 22);
Sqlist Lc;
InitList(&Lc);
InsertLIst(&L, 0, 1);
InsertLIst(&L, 1, 2);
InsertLIst(&L, 2, 3);
InsertLIst(&L, 3, 4);
InsertLIst(&L, 4, 5);
InsertLIst(&L, 5, 6);
InsertLIst(&L, 6, 7);
InsertLIst(&L, 7, 8);
MergeList(&Lc, &L, &Lb);
// DeleteList(&L, 5);
//UnionList(&L, &Lb);
// printf("%d\n", Lc.length);
TraverseList(&Lc);
return 0;
}