数据结构——线性表(c)

本文详细介绍了线性表的定义、特点,包括顺序存储结构和链式存储结构。顺序表以数组形式表示,便于随机访问但插入删除操作效率低;链表分为单链表、循环链表和双向链表,插入删除操作灵活但无法随机访问。此外,还探讨了顺序表和链表的优缺点以及它们在多项式表示和约瑟夫环问题中的应用。
摘要由CSDN通过智能技术生成

👍数据结构——线性表(c)


一、线性表的定义与特点(逻辑结构)

线性表:一个线性表是具有n个相同数据类型的数据元素的有限序列。

  • 每个数据元素的具体含义:在不同的情况下各不相同,可以是一个数,一个符号,也可以是一页书,甚至其他更复杂的信息。
  • 线性表中元素之间的关系:线性关系。
  • 线性表的长度:线性表中元素的个数n(n>=0),n=0时,称为空表。
  • 位序 a i \displaystyle a_i ai是第 i 个元素,称 i 为数据元素 a i \displaystyle a_i ai在线性表中的位序。

特点:
(1)表头元素:线性表存在唯一的一个被称作 “第一个” 的数据元素。
(2)表尾元素:存在唯一的一个被称作 “最后一个” 的数据元素。
(3)除第一个元素外,集合中的每个数据元素有且仅有一个直接前驱
(4)除最后一个元素外,集合中的每个数据元素有且仅有一个直接后继

二、线性表的顺序表示和实现(存储结构-顺序存储)

线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。
一般用数组表示。

1.顺序表

  1. 特点:
    (1)存储单元地址连续
    (2)逻辑上相邻的数据元素其物理位置也相邻
    (3)存储密度 100%
    (4)随机存取
  2. 优点
    (1)不需要额外的存储空间来表示元素之间的逻辑关系,存储密度高
    (2)可以随机地存取表中的任意一个元素
  3. 缺点
    (1)插入和删除元素时需要移动大量的元素
    (2)必须事先进行空间分配,大片连续空间分配不方便,改变容量不方便

2.基本操作的实现

  1. 定义顺序表类型(采用动态分配方式)
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
#define LISTINCREMENT 10 //线性表存储空间的分配增量

typedef struct{
   
    int *elem; //存储空间基址1
    int length; //当前长度
    int listsize; //当前分配的存储容量
}SqList;
  1. 函数声明
void InitList_Sq(SqList *L); //线性表初始化
void DestroyList_Sq(SqList *L); //销毁线性表
void ClearList_Sq(SqList *L); //将L置为空表
bool ListEmpty_Sq(SqList L); //判断L是否为空
int  ListLength_Sq(SqList L); //返回线性表L中数据元素的个数
int GetELem_Sq(SqList L, int i); //返回第i个数据元素的值
void ListInsert_Sq(SqList *L, int i, int a); //在i的位置插入元素
int ListDelete_Sq(SqList *L, int i); //删除线性表中第i个元素
void ListTraverse_Sq(SqList L); //线性表遍历
SqList* MergeList_Sq(SqList La, SqList Lb); //顺序表的合并算法
  1. 创建一个空的顺序表
//线性表初始化:创建一个空的顺序表
void InitList_Sq(SqList *L){
   
    L->elem = (int *)malloc(LIST_INIT_SIZE*sizeof(int));
    if(!L->elem){
   
        printf("内存分配失败!");
        return;
    }
    L->length = 0;
    L->listsize = LIST_INIT_SIZE;
}
  1. 判断顺序表是否为空表
//判断L是否为空表
bool ListEmpty_Sq(SqList L){
   
    if(L.length == 0){
   
        return true;
    }
    else
        return false;
}
  1. 返回线性表中数据元素的个数
//返回线性表L中数据元素的个数
int  ListLength_Sq(SqList L){
   
    return L.length;
}
  1. 返回线性表中第i个位置数据元素的值
//返回第i个数据元素的值
int GetELem(SqList L, int i){
   
    if(i < 1 || i > L.length){
   
        printf("越界!");
        exit(0);
    }
    else{
   
        return(L.elem[i-1]);
    }
}
  1. 在顺序表第i个数据元素前插入元素a
//在i的位置插入元素a
void ListInsert_Sq(SqList *L, int i, int a){
   
    int *newbase;
    //判断i的范围是否有效
    if(i < 1 || i > L->length+1){
   
        printf("越界!");
        return;
    }
    //判断当前存储空间是否已满,若已满,则重新申请一片更大的内存空间
    if(L->length >= L->listsize){
   
        newbase = (int *)realloc(L->elem,(L->listsize+LISTINCREMENT)*sizeof(int));
        if(!newbase){
   
            printf("内存分配失败!");
            return;
        }
        L->elem = newbase;
        L->listsize += LISTINCREMENT;
    }
    int *q = &(L->elem[i-1]);
    int *p;
    for(p = &(L->elem[L->length-1]); p>=q; --p){
   
        *(p+1) = *p;
    }
    *q = a;
    L->length++;
}
  1. 删除线性表中第i个元素并返回删除的元素的值
//删除线性表中第i个元素并返回删除的元素的值
int ListDelete_Sq(SqList *L, int i){
   
    if( i < 1 || i > L->length ){
   
        printf("越界!");
        return 0;
    }
    int *p = &(L->elem[i-1]);
    int e = *p;
    int *q = L->elem + L->length-1;
    for(++p; p <= q; ++p){
   
        *(p-1) = *p;
    }
    --L->length;
    return e;
}
  1. 顺序表的合并
//顺序表的合并算法
//已知顺序表La和Lb的元素是按值非递减排列
void MergeList_Sq(SqList La, SqList Lb, SqList *Lc){
   
    int *pa, *pb, *pc, *pa_last, *pb_last;
    pa = La.elem;
    pb = Lb.elem;
    Lc->listsize = Lc->length = La.length+Lb.length;
    pc = Lc->elem = (int*)malloc(Lc->listsize*sizeof(int));
    if(!Lc->elem){
     
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值