第二章 向量、栈和队列(二)—— 向量

本文探讨了向量作为数据结构的基础概念,包括其抽象数据类型、存储结构和随机存储的优势。向量在集合运算如并、交中的应用被详细阐述,特别是算法效率分析,涉及比较和插入操作的时间复杂度。此外,文章还介绍了约瑟夫问题的解决方案,通过向量模拟实现人员出列的顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

向量的抽象数据类型

  • 向量:由同一种数据类型的数据元素组成的线性表,因此向量的逻辑结构和一般线性表的逻辑结构是相同的。
  • 向量的存储结构:向量元素按照它们之间的关系排成一个线性序列 a0, a1, … , an-1,即 n 个向量元素的序号为 0 ~ n-1,这使得向量采用数组存储结构更自然,处理更方便。数组元素物理上的相邻关系隐含地提现了向量元素逻辑上的相邻关系。

随机存储结构:只要知道了整个向量的存储始地址、某向量元素的序号和每个向量元素所占的空间的大小,就可以立即求出该向量元素的存储地址,而且求任何一个向量的存储地址所花费的时间都相等。

  • 向量的抽象模型的实现:向量的抽象模型和线性表的抽象模型是相同的,只是在实现的方式上略有差异。
#ifndef _Vector_H
typedef int ElementType;
enum boolean {FALSE,TRUE};
typedef enum boolean Bool;
struct vector{
    ElementType *elements;
    int ArraySize;
    int VectorLength;
};

typedef struct vector Vector;

void GetArray(Vector *);                    /*申请向量的存储空间*/
void InitVector(Vector *, int size);        /*初始化一个空向量*/
ElementType GetNode(Vector *V, int i);      /*取向量的第 i 个表目*/
void FreeVector(Vector *);                  /*释放向量的存储空间*/
int Find(Vector *, ElementType);            /*在向量中查找*/
Bool Remove(Vector *, int i);               /*删除向量的第 i 个表目*/

#endif // _Vector_H


注:在具体编写头文件的时候,需要在头文件把具体的ElementType定义出来,或者用其他基本数据类型代替。

  • 具体代码实现:
void GetArray(Vector *V){
    V->elements = (ElementType *)malloc(sizeof(ElementType) * V->ArraySize);
    if(V->elements == NULL)
        printf("Memory Allocation Error!\n");
}


void InitVector(Vector *V, int size){
    if(size <=0)
        printf("Invalid Array Size\n");
    else{
        V->ArraySize = size;
        V->VectorLength = 0;
        GetArray(V);
    }
}

ElementType GetNode(Vector *V, int i){
    return (i<0||i>=V->VectorLength)?NULL:V->elements[i];
}

void FreeVector(Vector *V){
    free(V->elements);
}

int Find(Vector *V, ElementType x){
    int i;
    for(i=0;i<V->VectorLength;i++)
        if(V->elements[i]==x) return i;
    return -1;
}

Bool insert(Vector *V,ElementType x, int i){
    int j;
    if(V->VectorLength == V->ArraySize){
        printf("overflow\n");
        return FALSE;
    }
    else if(i<0||i>V->VectorLength){
        printf("position error\n");
        return FALSE;
    }
    else{
        for(j=V->VectorLength-1;j>=i;j--)
            V->elements[j+1]=V->elements[j];
        V->elements[i]=x;
        V->VectorLength++;
        return TRUE;
    }
}

Bool Remove(Vector *V, int i){
    int j;
    if(V->VectorLength == 0){
        printf("Vector is empty\n");
        return FALSE;
    }
    else if(i<0||i>V->VectorLength-1){
        printf("position error\n");
        return FALSE;
    }
    else
        for(j=i;j<V->VectorLength-1;j++)
            V->elements[j]=V->elements[j+1];
    V->VectorLength--;
    return TRUE;

}

注:
(1)在线性表数据元素的插入或者删除之前都需要判断位置与数组长度的关系。插入要考虑线性表是否为满表,删除需要考虑线性表是否为空表。

向量的应用

1.求集合的“并运算”和“交运算”

【并运算】

Vector *Union(Vector * Va,Vector * Vb)
/*把向量Va和Vb中的元素合并到Vc中,重复元素只保留一个*/
{
    int m,n,i,j,k;
    ElementType x;
    
    /*获取空向量Vc的存储空间*/
    Vector Vc = (Vector *)malloc(sizeof(Vector));
    
    /*初始化一个空向量*/
    n = Va->VectorLength;
    m = Vb->VectorLength;
    InitVector(Vc,m+n);
    
    /*把向量Va的元素存插入到Vc中*/
    j=0;
    for(i=0;i<n;i++){
        x = GetNode(Va,i);
        Insert(Vc,x,j);
        j++;
    }
    
    /*将Vb中有,Va中没有的元素插入到Vc中*/
    for(i=0;i<m;i++){
        x = GetNode(Vb,i);
        k = Find(Va,x);
        if(k == -1){
            Insert(Vc,x,j);
            j++;
        }
       return Vc;
    }
}

这里会出现一个警告:
warning: c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值