数据结构C语言版线性表算法,数据结构C语言线性表的顺序存储实现

原理是申请一段连续的内存空间,对这段内存空间进行相关操作实现基本的功能,大致实现了数据结构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 =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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值