数据结构(C/C++版)(1)线性表

本文根据哔哩哔哩王卓老师学习而写的一些,具体视频可看数据结构与算法基础(青岛大学-王卓)_哔哩哔哩_bilibili

线性表

一般线性表的模板

线性表分为两种,一种为顺序表,一种为链表,两个各有各的优缺点

顺序表的模板如下:

分为静态分配和动态分配两种

//静态分配

typedef struct

{

    int elem[LIST_INIT_SIZE];//地址

    int length;//实际变量个数

}SqList;//定义顺序表类型(与java中的class比较类似

//动态分配

typedef struct{

    ElemType *data;//(存放第一个元素地址)

    int length;

}SqList;

具体使用方法

关于使用进行逐步解析,如下:

SqList L;

L.data = (ElemType*)malloc(sizeof(ElemType)*MaxSize)

//ElemType规定划定类型是int or double or char等等;

//ElemType*即为指针,同于data;

//(ElemType*)强制转换

//sizeof(ElemType)类型长度

//sizeof(ElemType)*MaxSize类型长度乘以最大数

函数解析

需要头文件<stdlib.h>

malloc(m):开辟m字节长度的地址空间,并且返回空间首地址

free(p):释放指针p所指的变量的存储空间,彻底删除一个变量

C++的动态分配

new 类型名T(初值列表)-> int*p1 = new int;or int*p1 = new int(10);

    //功能:申请用于存放T类型对象的内存空间,并依初始只列表赋以初值结果

delete 指针p

    //释放空间;

C++中的参数传递

(1)类型,个数,顺序一致

(2)传值方式:

a.传值方式(实参)//二者使用的不同地址

b.传地址(形参与实参同一地址)

    参数为指针变量

    参数为引用类型

    参数为数组名

传地址方式 —— 数组名作参数

传递的是数组的首地址

对形参数组所做的任何改变都将反映到实参数组中

#include<iostream.h>

void main(){

    char a[10] = "hello";

    sub(a);

    cout<<a<<endl;

}

void sub(char b[]){

        b[] = "world";

}//输出的是world

引用类型作参数(更为推荐!)

即是给一个对象替代的名字

#include<iostream.h>

void main(){

    int i = 5;

    int &j = i;//引用型

    i = 7;

    cout<<"i = " <<i<<"j ="<<j;

}//输出i = 7,j = 7

线性表的一些操作

查找算法

顺序查找法:按值查找,有就输出第几个元素,没有就输出0

具体操作:从表的一端开始,逐个比较,找到返回位置序号,未找到,返回0

int LocateElem(SqList ElemType e){

    //查找值为e的元素

    for(i = 0;i<L.length,i++){

        if(L.elem[i] = e)

        return i+1;

    }

    return 0;

}

ASL平均查找长度:为确定记录在表中的位置,需要与给定值比较的关键字的个数的期望值,叫做查找算法的平均查找长度

插入算法

线性表的插入->顺序表的插入(时间复杂度:O(n))

  1. 插入位置在最后 ->直接放到最后一个数组
  2. 插入位置在中间 ->从后往前,依次往后搬
  3. 插入位置在最前面 ->同上

考虑两种异常情况:

  • 若有n个元素,则只可插入0~n+1的位置,若给出的不在范围内,则异常
  • 线性表元素已经满了,称为溢出->判断L.length的大小

算法思想:

  1. 判断插入位置是否合法
  2. 判断储存空间是否满了,若满了返回ERROR;
  3. ......
Status Lislinsert_Sq(SqList &L,int i.ElemType e){

    if(i<1 || i > L.length + 1)//i值不合法

    return ERROR;

    if(L.length == MAXSIZE)//储存空间已满

    return ERROR;

    for(j = L.length - 1;j >=i - 1;j--)

    L.elem[j+1] = L.elem[j];

    L.elem[i - 1] = e;

    L.length++;

    return OK;

}

算法时间主要耗费在移动元素的操作上

  • 若在尾结点,无需移动
  • 若在首节点,全往后移

删除算法

顺序表的删除

  • (1)删除位置在最后
  • (2)删除位置在中间 ->把后面的元素往前移动
  • (3)删除位置在最前面 ->从前往后,把后面的元素往前移动

算法思想:

  1. 判断删除位置i是否合法
  2. 将欲删除的元素保留在e中(可省略)
  3. 将i+1至n位的元素依次向前移动一个位置
  4. 表长减一,删除成功返回OK
Status ListDelete_Sq(SqList &L,int i){

    if((i<1)||(i >L.length))

    return ERROR;

    for(j = 1;j < L.length;j++)

    L.elem[j-1] = L.elem[j];

    L.length--;

    return OK;

}

额外的其他算法

  • 线性表的初始化
//InitList_Sq(顺序存储的)
Status InitList_Sq(SqList &L){
    L.elem = new ElemType[MAXSIZE];
    if(!.elem)//进行逻辑非运算,若有内容则为假
    {
        exit(OVERFLOW);//OVERFLOW -2
        }
        L.length = 0;
        return OK;//初始化成功放回1
//OK 1
}
  • 销毁线性表
void DestroyList(Sqlist &L){
    if(L.elem)//若有则为真 
    delete L.elem;
}
  • 清空线性表
void ClearList(SqList &L){
    L.length = 0;//将线性表长度设置为0
}
  • 求线性表的长度
int GetLength(SqList L){
    return(L.length);
}
  • 判断线性表L是否为空
int IsEmpty(SqList L){
    if(L.length == 0)
    return 1;
    else return 0;
}
  • 顺序表的取值(随机存取)
int GetElem(SqList L,int i,ElemType &e){
    if(i<1||i > L.length)
    return ERROR;
    //异常判断
    e = L.elem[i - 1];
    return OK;
}

举例

图书管理项目

#include<stdio.h>

#define MAXSIZE 100;
//类比java里的class
typedef struct book //每本书的信息
{
    char no[20];//ISBN码
    char name[50];//图书名字
    float price;//图书价格
}Book;
//链表(结构体)
typedef struct 
{
    Book *elem;
    int length;
}SqList;

学校老师提供的一个线性表的代码

#include<stdio.h>
#include<stdlib.h>
 
 //定义顺序表的元素类型为整型
 //最大长度为50
typedef int ElemType;//定义ElemType为整型
#define MAXSIZE 50
 
 //顺序表的结构体类型以及命名为SeqList
 //包含了一个长度为50的()类型数组
 //以及一个整型变量last记录长度
typedef struct
{
    ElemType data[MAXSIZE];
    int last;
}SeqList;

//创建了一个函数
SeqList* CreatSeqList()//前面是返回类型 后面是名称
{
    //动态分配内存空间
    //指针变量
    SeqList *head=(SeqList *)malloc(sizeof(SeqList));
    //把last赋值为-1
    head->last=-1;
    int x;
    //输入-1视为结束
    printf("input the element of the list, -1 is end\n");
    scanf("%d",&x);//输入
    //每输入一个数不为-1的时候last都加1
    //把输入的数x赋值到data[last]里面
    //再输入下一个数
    while(x != -1 && head->last < MAXSIZE) {
        head->last++;
        head->data[head->last] = x;
        scanf("%d",&x);
    }
    return head;//最后返回头指针
}
//显示所有元素
void ShowSeqList(SeqList *L)
{
    // SeqList *p=L;
    for(int i = 0; i <= L->last; i++)//遍历数组
        printf("%d ",L->data[i]);
}

int  Locate(SeqList *L, ElemType e) {
    //todo, 编写查找运算的代码
}

int  InsList(SeqList *L,int i,ElemType e) {
    //todo, 编写插入运算的代码
}

int  DelList(SeqList *L,int i, ElemType *e) {
    //todo, 编写删除运算的代码
}

int main()
{
    SeqList *L;//定义L的指针
    L = CreatSeqList();//L的指针指向结构体
    ShowSeqList(L);
    //todo, 测试查找运算
    
    //todo, 测试插入运算

    //todo, 测试删除运算
    return 1;
}

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值