顺序表的相关操作的解读

// 顺序表2.cpp : 定义控制台应用程序的入口点。
//编译预处理:文件包含
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
//宏定义:预编译指令,定义符号常量,性能上没有常变量优越
#define LIST_INIT_SIZE 100//线性表存储空间的初始分配量
#define LIST_INCREMENT 10//线性表存储空间的分配增量
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
//typedef为数据类型定义别名,此处可增强程序的可移植性
typedef int  ElemType;
typedef int Status;//其值为函数结果状态码
                   //动态分配的顺序表类型定义
typedef struct
{
    ElemType *elem;//定义存储空间基址指针
    int length;//顺序表当前长度
    int listsize;//顺序表当前分配的存储容量
}SqList;
//顺序表的初始化:
Status InitList_Sq(SqList &L)
{
    L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));//线性表存储空间的初始分配量,这里没有指针域,所以为ElemType
    if (!L.elem) exit(OVERFLOW);//存储分配失败
    L.length = 0;//空表长度为0
    L.listsize = LIST_INIT_SIZE;//初始化存储容量
    printf("初始存储容量为:%d\t存储空间基址为:%d\n", L.listsize,*L.elem);
    return OK;
}
//
//插入结点:1.插入位置合法性判断;2.存储空间内存是否已满判断;3.插入位置后的元素右移
//时间复杂度:o(n)
Status ListInsert_Sq(SqList &L, int i, ElemType e)//&不表示取地址,表引用,只在结构体发生了变化的情况下使用
{
    ElemType *newbase;//用于存储新结点的存储单元地址
    ElemType *p, *q;
    if (i<1 || i>L.length + 1)//这里考虑在对应位置上放元素,可插入位置从第一个位置到最后一个位置+1,所以不需要考虑数组的0位置
        return ERROR;
    if (L.length >= L.listsize)//超过了当前分配的存储容量
    {
        newbase = (ElemType *)realloc(L.elem, (LIST_INIT_SIZE + LIST_INCREMENT) * sizeof(ElemType));
        if (!newbase)
            exit(OVERFLOW);
        L.elem = newbase;//更新当前存储空间基址
        L.listsize += LIST_INCREMENT;//增加存储空间容量
    }
    q = &(L.elem[i - 1]);//此处L.elem可近似看似数组的首地址,q为插入位置在内存单元中的地址
    for (p = &(L.elem[L.length - 1]);p >= q;--p)//p为尾结点的地址
        *(p + 1) = *p;//将p对应内存单元中的数据元素赋给p+1,即:数据元素右移
    *q = e;//插入e
    ++L.length;//当前表长+1
    return OK;
}
//删除结点:1.判断删除位置是否合法;2.删除位置后的元素左移
//时间复杂度:o(n)
Status ListDelete_Sq(SqList &L, int i, ElemType *e) {//e为指向ElemType类型的指针变量
    ElemType *p, *q;
    if (i<1 || i>L.length)
        return ERROR;
    p = &L.elem[i - 1];//取i-1位置的地址
    e = p;
    //q = L.length + L.elem - 1;
    q = &(L.elem[L.length - 1]);
    for (++p;p <= q;++p)
        *(p - 1) = *p;
    --L.length;//此处不释放内存单元是因为采用的是动态内存分配,下次使用时直接覆盖,所以不需要释放
    return OK;
}
//按值查找位序:不断的将e与顺序表内的数据元素进行比较
//平均时间复杂度:O(n)
/*int  LocateElem_Sq(SqList L, ElemType e)
{
int i = 0;
for (i = 0;i < L.length;i++)
if (e == L.elem[i])
return i + 1;
return ERROR;
}*/
Status compare(ElemType e1, ElemType e2)
{
    if (e1 == e2) {
        return OK;
    }
    else {
        return ERROR;
    }
}
int  LocateElem_Sq(SqList L, ElemType e, Status(*compare)(ElemType, ElemType))//函数指针:Status表示函数指针变量compare所指向的函数的返回值类型,注意区分:Status *compare()表示compare是一个返回值为指针类型的函数
{
    int i;
    ElemType *p;
    i = 1;
    p = L.elem;
    while (i <= L.length && !(*compare)(*p++, e))//*p++<==>*p;p=p+1;
        ++i;
    if (i <= L.length)
        return i;
    else
        return 0;
}
int TraverseList(SqList L) {/*L为顺序表*/
    int i;
    for (i = 0;i < L.length;i++)
        printf("%d\t", L.elem[i]);
    printf("\n");
    return 1;//函数结束语句
}
void input_data(SqList &L)
{
    int n, i;
    ElemType elem;
    printf("input the number of data:\n");
    scanf("%d", &n);
    printf("input the data:\n");
    for (i = 1;i <= n;i++) {
        scanf("%d", &elem);
        ListInsert_Sq(L, i, elem);//L?
    }
}
//将LA、LB归并为一个新的线性表LC,LC中的数据元素按值非递减有序排列
/*void MergeList_Sq(SqList La,SqList Lb,SqList *Lc)
{
    ElemType *pa, *pb, *pc, *pa_last, *pb_last;
    Lc->listsize = Lc->length = La.length + Lb.length;
    pa = La.elem;
    pb = Lb.elem;
    pc = Lc->elem = (ElemType *)malloc(Lc->listsize * sizeof(ElemType));
    if (!Lc->elem)
        exit(OVERFLOW);//存储分配失败
    pa_last = La.elem + La.length - 1;
    pb_last = Lb.elem + Lb.length - 1;
    while (pa <= pa_last && pb <= pb_last)
    {
        if (*pa <= *pb)
            *pc++ = *pa++;
        else
            *pc++ = *pb++;
    }
    while (pa <= pa_last)//*pc++ = *pa++;//插入La的剩余元素
    {
        pb = pa + 1;
        if (*pa <= *pb)
            *pc++ = *pa++;
    }
    while (pb <= pb_last)//*pc++ = *pb++;
    {
        pa = pb + 1;
        if (*pb <= *pa)
            *pc++ = *pb++;
    }
}*/
//初始条件:顺序表已存在 操作结果:销毁线性表L
Status DestroyList(SqList &L)
{
    free(L.elem);
    L.length = 0;
    L.listsize=0;
    return OK;
}
//初始条件:顺序表已存在;操作结果:将L重置为空表
Status ClearList(SqList &L)
{
    L.length = 0;
    return OK;
}
//初始条件:线性表L已经存在;操作结果:若L为空表,返回TRUE,否则返回FALSE
Status ListEmpty(SqList L)
{
    if (L.length == 0)
        return TRUE;
    else
        return FALSE;
}
//初始条件:线性表L已存在;操作结果:返回L中数据元素的个数
int  ListLength(SqList L)
{
    return L.length;
}
//初始条件:线性表L已存在,1<=i<=ListLength(L);操作结果:用e返回L中第i个数据元素的值;
Status GetElem(SqList L, int i, ElemType *e)
{
    if (i<1 || i>ListLength(L))
        return ERROR;
    e = &L.elem[i - 1];
    //e = L.elem + i - 1;
    return OK;
}
//特殊的自定义函数:负责协调组装其它函数;
//函数调用的三种类型:1.作为语句(完成一定操作);2.作为表达式的一部分;3.作为函数的实参被调用
//调用函数时,系统为函数的形参分配存储单元,实参和形参之间是一种单向传递关系,即:只将实参的值赋给形参,修改形参不影响实参
int main()
{
    SqList L,LB,LC;//定义一个SqList类型的数据对象
    ElemType elem;
    int  i;
    printf("input the data of LA:\n");
    InitList_Sq(L);//L表示结构体类型的变量,相当于变量a
    input_data(L);
    TraverseList(L);//每个函数在编译、连接后都会占用一段连续的内存单元,内存中存放函数代码的首地址称为入口地址
    printf("the length of the sq:%d\n",ListLength(L));
   //ClearList(L);
    printf("input the data of LB:\n");
    InitList_Sq(LB);//L表示结构体类型的变量,相当于变量a
    input_data(LB);
    TraverseList(LB);//每个函数在编译、连接后都会占用一段连续的内存单元,内存中存放函数代码的首地址称为入口地址
/*    printf("input the  value of i in the LA:\n");
    scanf("%d", &i);
    printf("input the elem of i in the LA:%d\n",GetElem(L,i,&elem));
    printf("input the location of deleted elem in the LA:\n");
    scanf("%d", &i);
    ListDelete_Sq(L, i, &elem);//函数完成一定的操作,作为语句被调用,L?
    TraverseList(L);
    printf("input the elem of seeking in the LA:\n");
    scanf("%d", &elem);
    //printf("\n the location of elem in the table:%d\n", LocateElem_Sq(L, elem));
    printf("\n the location of elem in the LA in the table:%d\n", LocateElem_Sq(L, elem, compare));//LocateElem_Sq()作为实参被调用,compare函数名代表了函数的入口地址,只需将函数名赋给函数指针变量
    */
    /*printf("MergeList:\n");
    MergeList_Sq(L, LB, &LC);*/
    TraverseList(LC);
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值