数据结构学习笔记(1)——线性表

用到的宏定义

#define ELEMTYPE int //数据类型

#define MAXSIZE 10   //定义最大长度
#define INITSIZE 10 //默认最大长度

#define ERROR -1
#define OK 1

静态线性表

结构体

typedef struct Sqlist
{
    /* data */
    ELEMTYPE data[MAXSIZE];
    ELEMTYPE length;	//长度
} SqList;
结构体调用方式:

1,通过结构体变量定义
		Sqlist L;
L为Sqlist类型的结构体变量,利用L.data[i-1]可以访问序号为i的表元素,L.length为顺序表长度
2,通过指针变量定义
        Sqlist *L;
L为Sqlist类型的指针变量,利用L->data[i-1]可以访问序号为i的表元素,而L->length为顺序表的长度。

静态初始化一个顺序表

void InitSqList(SqList * L, ELEMTYPE len)
{
    L->length = len;
}

查找:

线性表具有两种基本查找运算:
(1)按照序号查找GetData(L, i):要求查找线性表中第i个元素,其结果是直接返回L.elem[i-1],或者直接返回L->data[i-1].
(2)按照内容查找Locate(L, e):要求查找数据元素e在线性表L中的位置。如果在表L中找到与e相等的元素则返回其在表中的序号;如果没有,则返回一个空序号,如-1.

按位查找(给出位号,查找这一尾号的元素)
ELEMTYPE Getdata(SqList * L, ELEMTYPE i)
{
    return L->data[i - 1];
}
按值查找(已知元素,查找位号)

(方法1):

int Locatdata1(SqList * L, ELEMTYPE value)
{
    for (int i = 0; i < L->length; i++)
    {
        if (value == L->data[i])
        {
            return (i + 1); //返回位序
        }
        return ERROR ;
    }
}

(方法2)

int  Locatdata2(SqList * L, ELEMTYPE value)
{
    int i = 0;
    while((i < L->length)&&(value != L->data[i]))
    {
        i++;
    }
    if((i < L->length)) return(i+1);
    else return ERROR ;
}

算法时间复杂度的分析:算法中的基本操作是“移动元素”,在最坏的情况下(e为最后一个元素)为 L.last。此算法的时间复杂度为:O (n)

插入

在线性表 L= (a1,…a i-1,ai, ai+1,…,an) 中的第i(1≦i≦n)个元素位置上(元素ai之前)插入一个新结点e,使其成为线性表:L=(a1,…a i-1,e,ai,ai+1,…,an)

思路:
(1) 将线性表L中的第i个至第n个结点后移一个位置。
(2) 将结点e插入到结点ai-1之后。
(3) 线性表长度增加1。

事先应判断:
(1)插入位置i 是否合法,表是否已满。
应当有1≤i≤n+1 或 i=[1,n+1],n为表中元素个数
(2)判断线性表空间是否足够。

int InsList(SqList *L, int i, ELEMTYPE e) 
{
    /*在顺序表L的第i个元素前插入e,表长n=L->length+1, 1<=i<=L->length+2*/
    int k;
    if(i<1 || i>L->length+2)        /*用于挪动i及其后面的元素*/
    {
        printf("插入i位置不合法");   //i值不合法
        return ERROR;
    }
    if(L->length>MAXSIZE)           
    {
        printf("表已满无法插入");   //当前存储空间已满
        return ERROR;
    }
    for(k=L->length;k>=i-1;k--)    //第i个元素开始依次后移
    {
        L->data[k+1] = L->data[k];
    }
    L->data[i-1] = e;
    L->length++;            //表长加一
    return OK;
}

删除

算法思想:删除第i(1≤i≤n)个元素时,将第(i+1)至第n(共n-i)个元素逐一向前移动一个位置。

在线性表 L=(a1,…a i-1,ai, ai+1,…,an) 中删除结点ai(1≦i≦n),使其成为线性表:
L= (a1,…ai-1,ai+1,…,an)
实现步骤:
(1) 将线性表L中的第i+1个至第n个结点依此向前移动一个位置。
(2) 线性表长度减1。

int ListDelete(SqList *L,int i,ELEMTYPE *e)
{ /*删除线性表L第i个元素并用指针参数e返回其值,1<=i<=L.length+1*/
    int  k; 
    if (i<1||i>L->length+1)               //i值不合法      
    { 
    printf("删除位置不合法"); 
    return ERROR;     
    }  
    *e=L->data[i-1]; 	                //将被删除元素的值赋给指针e所指变量  
    for(k=i;k<=L->length;k++)           //被删除元素之后的元素左移         
    L->data[k-1]= L->data[k]; 
    L->length--;		                //表长减1  
    return (OK);                            
 }//ListDelete

合并

已知 :有两个顺序表LA和LB,其元素均为非递减有序排列,编写一个算法,将它们合并成一个顺序表LC,要求LC也是非递减有序排列。
算法思想 :设表LC是一个空表,为使LC也是非递减有序排列,可设两个指针i、j分别指向表LA和LB中的元素,若LA.elem[i]>LB.elem[j],则当前先将LB.elem[j]插入到表LC中,若LA.elem[i]≤LB.elem[j] ,当前先将LA.elem[i]插入到表LC中,如此进行下去,直到其中一个表被扫描完毕,然后再将未扫描完的表中剩余的所有元素放到表LC中。

void merge(SeqList *LA,  SeqList *LB,  SeqList *LC)   //有序表合并
{ 
    int i=0,j=0,k=0;     //预定义三个变量,表示LA、LB、LC中元素序号
    while(i<=LA->length&&j<=LB->length)   //LA、LB均不空时
    if(LA->data[i]<=LB->data[j])  //如果LA中元素小于LB中元素
    {	
        LC->data[k]= LA->data[i];  
        i++;  k++; 
    } //将LA中元素插入LC
    else            //否则将LB中元素插入LC
    {
        LC->data[k]=LB->data[j];   
        j++; k++;
    }
    while(i<=LA->length) /*当表LA有剩余元素则将余下的元素赋给表LC*/
    {	 
        LC->data[k]= LA->data[i];  
        i++;  k++;  }
    while(j<=LB->length)/*当表LB有剩余元素则将余下的元素赋给表LC*/
    {
        LC->data[k]= LB->data[j];   
        j++;  k++;    
    }
    LC-> length =LA-> length +LB-> length+1;   //最后将表C长度赋值
} 

动态线性表

结构体

typedef struct Seqlist
{
    /* data */
    ELEMTYPE *data;   
    ELEMTYPE MaxSize; //顺序表最大容量
    ELEMTYPE length;  //顺序表当前长度
} SeqList;
  • 调用方式同静态

动态分配,初始化

void InitSeqList(SeqList * L)
{
	L->data = (ELEMTYPE *)malloc(INITSIZE * sizeof(ELEMTYPE));
	L->length = 0;
	L->MaxSize = INITSIZE;
}

增加动态数组的长度

>len:需要增加的长度
void IncreaseSize(SeqList * L, int len)
{
 ELEMTYPE *p = L->data; //存放改变之前的数据
 L->data = (ELEMTYPE *)malloc((L->MaxSize + len) * (sizeof(ELEMTYPE)));
 for (int i = 0; i < L->length; i++)
 {
     L->data[i] = p[i]; //旧数据复制到新区域
 }
 L->MaxSize = L->MaxSize + len;
 free(p); //释放原来的内存空间
}
  • 动态线性表操作方式思路基本与静态线性表相同,可直接参考

代码文件放在码云上,需要请自取:链接

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值