【数据结构】C语言实现线性表(顺序表,单链表)

线性表

定义

线性表是一种相当灵活的数据结构,其长度可以根据需要增长或缩短,对线性表的数据元素不仅可以进行访问,还可以进行插入和删除等操作。

基本操作

线性表的基本操作包括

函数名称 功能
Init 初始化线性表
Destory 销毁线性表
Clear 清空线性表
IsEmpty 判断线性表是否为空
Length 获取线性表的长度
GetElem 获取线性表中某个元素的值
Locate 在线性表中查找指定元素
PriorElem 返回指定元素的前驱元素的值
NextElem 返回指定元素的后继元素的值
Insert 在指定位置插入元素
Delete 删除指定位置元素
Traverse 遍历线性表

抽象数据类型

ADT List{
    数据对象:D = {a[i] | a[i]属于ElemSet, i=0,1,2,3,...,n, n>=0}
    数据关系:R = {<a[i-1],a[i]> | a[i-1],a[i]属于D, i=1,2,,...,n, n>=1}
    基本操作:
        Init(&L)
            操作结果:构建一个空的线性表L
        Destory(&L)
        初始条件:线性表L已存在
            操作结果:销毁线性表 
        Clear(&L)
        初始条件:线性表L已存在
            操作结果:清空线性表
        IsEmpty(L)
            初始条件:线性表L已存在
            操作结果:判断线性表是否为空,若为空返回true,否则返回false
        Length(L)
            初始条件:线性表L已存在
            操作结果:获取线性表的长度
        GetElem(L,i,&e)
            初始条件:线性表L已存在,且 1 <= i <=Length(L)
            操作结果:获取线性表中第i个元素的值,并用e返回
        Locate(L,e)
            初始条件:线性表L已存在
            操作结果:在线性表中查找等于e的元素,并返回其位置,否则返回值为0
        PriorElem(L,cur_e,&pre_e)
            初始条件:线性表L已存在
            操作结果:在线性表中查找等于e的元素的前驱元素,并用pre_e返回前驱元素的值,若不存在元素e,则pre_e为NULL
        NextElem(L,cur_e,&next_e)
            初始条件:线性表L已存在
            操作结果:在线性表中查找等于e的元素的后继元素,并用next_e返回后继元素的值,若不存在元素e,则next_e为NULL
        Insert(&L,i,e)
            初始条件:线性表L已存在,且 1 <= i <=Length(L)+1
            操作结果:在指定位置i插入元素e
        Delete(&L,i)
            初始条件:线性表L已存在,且 1 <= i <=Length(L)
            操作结果:删除指定位置i上的元素
        Traverse(L)
            初始条件:线性表L已存在
            操作结果:遍历线性表
}ADT List

C语言实现顺序表

List.h头文件

#pragma once
#ifndef LIST_H
#define LIST_H

#define status int
#define OK 1
#define Error 0

#define BASESIZE 10 //顺序表基本长度

// 元素类型
typedef int ElemType;
// 顺序表结构
typedef struct List{
    
    
    ElemType *data; // 数据域
    int length; // 长度
    int MAX_SIZE;   // 数据域最大长度
}list;
/*
    参数:
        - *L:顺序表指针
    初始条件:
        - 无
    功能:
        - 初始化顺序表
*/
void Init(list *L);
/*
    参数:
        - *L:顺序表指针
    初始化条件:
        - 顺序表L存在
    操作结果:
        - 销毁顺序表
*/
void Destroy(list *L);
/*
    参数:
        - *L:顺序表指针
    初始化条件:
        - 顺序表L存在
    操作结果:
        - 清空线性表
*/
void Clear(list *L);
/*
    参数:
        - L:顺序表
    初始化条件:
        - 顺序表L存在
    操作结果:
        - 判断线性表是否为空
*/
status IsEmpty(list L);
/*
    参数:
        - L:顺序表
    初始化条件:
        - 顺序表L存在
    操作结果:
        - 返回顺序表L的长度
*/
int Length(list L);
/*
    参数:
        - L:顺序表
        - i:第i个位置
        - e:返回指针
    初始化条件:
        - 顺序表L存在
        - 1 <= i <= Length(L)
    操作结果:
        - 获取顺序表中第i个元素的值,并用e返回
*/
status GetElem(list L, int i, ElemType *e);
/*
    参数:
        - L:顺序表
    初始化条件:
        - 顺序表L存在
    操作结果:
        - 在顺序中查找等于e的元素,并返回其位置,否则返回值为0
*/
int Locate(list L,ElemType e);
/*
    参数:
        - L:顺序表
        - cur_e:查找元素
        - pre_e:前驱元素
    初始化条件:
        - 顺序表L存在
    操作结果:
        - 在线性表中查找等于e的元素的前驱元素,并用pre_e返回前驱元素的值,若不存在元素e,则pre_e为NULL
*/
status PriorElem(list L,ElemType cur_e,ElemType *pre_e);
/*
    参数:
        - L:顺序表
        - cur_e:查找元素
        - next_e:前驱元素
    初始化条件:
        - 顺序表L存在
    操作结果:
        - 在线性表中查找等于e的元素的后继元素,并用next_e返回前驱元素的值,若不存在元素e,则next_e为NULL
*/
status NextElem(list L,ElemType cur_e,ElemType *next_e);
/*
    参数:
        - *L:顺序表指针
        - i:插入元素位置
        - e:插入元素
    初始化条件:
        - 顺序表L存在
        - 1 <= i <= Length(L)+1
    操作结果:
        - 在指定位置i插入元素e
*/
void Insert(list *L,int i,ElemType e);
/*
    参数:
        - *L:顺序表指针
        - i:删除元素位置
    初始化条件:
        - 顺序表L存在
        - 1 <= i <= Length(L)
    操作结果:
        - 删除指定位置i上的元素
*/
void Delete(list *L,int i);
/*
    参数:
        - L:顺序表
    初始化条件:
        - 顺序表L存在
    操作结果:
        - 遍历输出顺序表
*/
void Traverse(list L);

#endif // !LIST_H

List.c源文件

#include <stdio.h>
#include <stdlib.h>
#include "List.h"

void Init(list *L){
    
    
    L->data = (int *)malloc(BASESIZE * sizeof(int));
    L->length = 0;
    L->MAX_SIZE = BASESIZE;
}

void Destroy(list *L){
    
    
    if(L != NULL){
    
    
        free(L->data);

        L->data = NULL;
        L->length = 0;
        L->MAX_SIZE = 0;

        L = NULL;
    }
}

void Clear(list *L){
    
    
    if(L != NULL){
    
    
        free(L->data);

        Init(L);
    }
}

status IsEmpty(list L){
    
    
    if(Length(L) == 0) return OK;
    else return Error;
}

int Length(list L){
    
     
    return L.length;
}

status GetElem(list L, int i, ElemType *e){
    
    
    if(i <= Length(L) && i >= 1){
    
    
        *e = L.data[i-1];
        return OK;
    }else{
    
    
        return Error;
    }
}

int Locate(list L,ElemType e){
    
    
    for(int i=0;i<L.length;i++){
    
    
        if(L.data[i]==e){
    
    
            return i + 1;
        }
    }
    return 0;
}

status PriorElem(list L,ElemType cur_e,ElemType *pre_e){
    
    
    int i = Locate(L, cur_e);
    if(i != 0){
    
    
        ElemType x;
        if(GetElem(L, i-1, &x)){
    
    
            *pre_e = x;
            return OK;
        }else{
    
    
            return Error;
        }
    }else{
    
    
        return Error;
    }   
}

status NextElem(list L,ElemType cur_e,ElemType *next_e){
    
      
    int i = Locate(L, cur_e);
    if(i!=0){
    
    
        ElemType x;
        if(GetElem(L, i+1, &x)){
    
    
            *next_e = x;
            return OK;
        }else{
    
    
            return Error;
        }
    }else{
    
    
        return Error;
    }
}

void Insert(list *L,int i,ElemType e){
    
    
    if(L != NULL){
    
    
        if(i >= 1 && i<= Length(*L)+1){
    
    
            for(int j = Length(*L); j>=i; j--){
    
    
                L->data[j] = L->data[j-1];
            }

            L->data[i-1] = e;
            L->length++;
            // 内存自动扩展机制
            if(L->length == L->MAX_SIZE){
    
    
                L->MAX_SIZE *= 2;
                L->data = (int*)realloc(L->data,L->MAX_SIZE * sizeof(int));
            }
        }
    }
}

void Delete(list *L,int i){
    
    
    if(L != NULL){
    
    
        if(i>=1 && i<= Length(*L)){
    
    
            for(int j=i; j<Length(*L); j++){
    
    
                L->data[j-1] = L->data[j];
            }
            L->length--;
            // 内存自动释放机制
            if(L->MAX_SIZE > BASESIZE && L->length < L->MAX_SIZE/2){
    
    
                L->MAX_SIZE /= 2;
                L->data = (int*)realloc(L->data,L->MAX_SIZE * sizeof(int));
            }
        }
    }
}

void Traverse(list L){
    
       
    for(int i=1; i<= Length(L); i++){
    
    
        printf("%d ", L.data[i-1]);
    }
}

完整的程序(包含测试文件)

csdn文库:

参考文献

  • 【1】严蔚敏,李冬梅,吴伟民. 数据结构(C语言版) 北京:人民邮电出版社

猜你喜欢

转载自blog.csdn.net/qq_62094479/article/details/129861605