线性表的存储结构和链式存储结构的比较

1. 线性表的顺序存储结构——顺序表

        顺序表基本运算的实现:

       1)建立顺序表

        其方法是将给定的含有 n 个元素的数组的每个元素依次放入到顺序表中,并将 n 赋给顺序表的长度成员。算法如下:
      
    void CreateList(SqList *&L,ElemType a[],int n)  
     //建立顺序表
    {  int i;
       L=(SqList *)malloc(sizeof(SqList));
       for (i=0;i<n;i++)
	  L->data[i]=a[i];
         L->length=n;
    }
      2)顺序表基本运算算法
           (1)初始化线性表InitList(L)
        该运算的结果是构造一个空的线性表 L 。实际上只需将 length 成员设置为 0 即可。
   <strong> void InitList(SqList *&L)   //引用型指针
    {  L=(SqList *)malloc(sizeof(SqList));	
       //分配存放线性表的空间
       L->length=0;
    }</strong>
       本算法的时间复杂度为 O(1)
           (2)销毁线性表       
        该运算的结果是释放线性表 L 占用的内存空间。      
   <strong> void DestroyList(SqList *&L)
    {
      free(L);
    }</strong>
       本算法的时间复杂度为 O(1)
     3)判定是否为空表ListEmpty(L)
        该运算返回一个值表示 L 是否为空表。若 L 为空表,则返回 true ,否则返回 false    
  <strong> bool ListEmpty(SqList *L)
  {
	return(L->length==0);
  }</strong>
       本算法的时间复杂度为 O(1)
     4)求线性表的长度ListLength(L)     
      该运算返回顺序表 L 的长度。实际上只需返回 length 成员的值即可。
   <strong>int ListLength(SqList *L)
   {
	return(L->length);
   }</strong>
      本算法的时间复杂度为 O(1)
     5)输出线性表DispList(L)
      该运算当线性表 L 不为空时 , 顺序显示 L 中各元素的值。   
<strong>   void DispList(SqList *L)
   {	int i;
	if (ListEmpty(L)) return;
	for (i=0;i<L->length;i++)
		printf("%c",L->data[i]);
	printf("\n");
   } </strong>
       本算法中基本运算为 for 循环中的 printf 语句,故时间复杂度为 :   O(L - >length) O( n )
      6)求某个数据元素值GetElem(L,i,e)   
      该运算返回 L 中第 i 1 i ListLength(L) )个元素的值,存放在 e 中。
   <strong>bool GetElem(SqList *L,int i,ElemType &e)
   {	if (i<1 || i>L->length)  return false;
	e=L->data[i-1];
	return true;
   }</strong>
        本算法的时间复杂度为 O(1)
      7)按元素值查找LocateElem(L,e) 
      该运算顺序查找第 1 个值域与 e 相等的元素的逻辑位序。若这样的元素不存在,则返回值为 0  
  <strong> int LocateElem(SqList *L, ElemType e)
   {	int i=0;
	while (i<L->length && L->data[i]!=e) i++;
	if (i>=L->length)  return 0;
	else  return i+1;
   }</strong>
       本算法中基本运算为 while 循环中的 i++ 语句,故时间复杂度为 : O(L -> length) O( n )
     8)插入数据元素ListInsert(L,i,e)      
      该运算在顺序表 L 的第 i 1 i ListLength(L)+1 )个位置上插入 新的元素 e 。如果 i 值不正确,则显示相应错误信息;否则将顺序表 原来第 i 个元素及以后元素均后移一个位置,移动方向从右向左, 如下图所示,腾出一个空位置插入新元素,最后顺序表长度增 1        
    <strong>bool ListInsert(SqList *&L,int i,ElemType e)
    {  int j;
       if (i<1 || i>L->length+1)
	return false;	//参数错误时返回false
        i--;			//将顺序表逻辑序号转化为物理序号
       for (j=L->length;j>i;j--)	//将data[i..n]元素后移一个位置
	 L->data[j]=L->data[j-1];
         L->data[i]=e;			//插入元素e
         L->length++;			//顺序表长度增1
       return true;			//成功插入返回true
     }</strong>
        插入算法的平均时间复杂度为 O( n )
      9)删除数据元素ListDelete(L,i,e)       
        该运算删除顺序表 L 的第 i 1 i ListLength(L) )个元素。如果 i 值不正确,则显示相应错误信息;否则将线性表第 i 个元素以后元素均向 前移动一个位置,移动方向为从左向右,如下图所示,这样覆盖了原来的第 i 个元素,达到删除该元素的目的,最后顺序表长度减 1

   <strong> bool ListDelete(SqList *&L,int i,ElemType &e)
    {  int j;
       if (i<1 || i>L->length)	 //参数错误时返回false
	return false;
        i--;		//将顺序表逻辑序号转化为物理序号
        e=L->data[i];
        for (j=i;j<L->length-1;j++)  //将data[i..n-1]元素前移
		L->data[j]=L->data[j+1];
           L->length--;			  //顺序表长度减1
        return true;			  //成功删除返回true
    }</strong>
        删除算法的平均时间复杂度为 O( n )

2.线性表基本运算在单链表上的实现      
      1)初始化线性表InitList(L)  
  <strong> void InitList(LinkList *&L)
   {  L=(LinkList *)malloc(sizeof(LinkList));
   	 //创建头节点
    L->next=NULL;
   }</strong>
       本算法的时间复杂度为 O(1)
     2)销毁线性表DestroyList(L)
      释放单链表 L 占用的内存空间。即逐一释放全部节点的空间。       
   <strong>void DestroyList(LinkList *&L)
   {  LinkList *pre=L,*p=p->next;  //pre指向*p的前驱节点
   while (p!=NULL)	//扫描单链表L
   {  free(pre);		//释放*pre节点
	pre=p;		//pre、p同步后移一个节点
	p=pre->next;
   }
   free(pre); //循环结束时,p为NULL,pre指向尾节点,释放它
   }</strong>
     本算法的时间复杂度为O(n)
     3)判线性表是否为空表ListEmpty(L)
      若单链表 L 没有数据节点,则返回真,否则返回假。       
  <strong> bool ListEmpty(LinkList *L)
   {
  return(L->next==NULL);
   }</strong>
     本算法的时间复杂度为 O(1)
    4)求线性表的长度ListLength(L)
    返回单链表 L 中数据节点的个数。     
   <strong>int ListLength(LinkList *L)
   { int n=0;
     LinkList *p=L;	//p指向头节点,n置为0(即头节点的序号为0)
      while (p->next!=NULL)
      {	n++;
	p=p->next;
      }
     return(n);	//循环结束,p指向尾节点,其序号n为节点个数
   }</strong>
     本算法的时间复杂度为 O(n)
    5)输出线性表DispList(L)
     逐一扫描单链表 L 的每个数据节点,并显示各节点的 data 域值。    
  <strong>void DispList(LinkList *L)
  {  LinkList *p=L->next;	//p指向开始节点
   while (p!=NULL)	//p不为NULL,输出*p节点的data域
   {	printf("%d ",p->data);
	p=p->next;		//p移向下一个节点
   }
   printf("\n");
  }</strong>
     本算法的时间复杂度为O(n)
    6)求线性表L中指定位置的某个数据元素GetElem(L,i,&e)
     在单链表 L 中从头开始找到第 i 个节点,若存在第 i 个数据节点,则将其 data 域值赋给变量 e
  <strong> bool GetElem(LinkList *L,int i,ElemType &e)
   {  int j=0;
      LinkList *p=L;	//p指向头节点,j置为0(即头节点的序号为0)
      while (j<i && p!=NULL)	//找第i个节点
      {	j++;
	p=p->next;
      }
      if (p==NULL)	//不存在第i个数据节点,返回false
 	return false;
     else		//存在第i个数据节点,返回true
      {  e=p->data;
  	return true;
      }
   }</strong>
     本算法的时间复杂度为O(n)
     7)按元素值查找LocateElem(L,e)
      在单链表 L 中从头开始找第 1 个值域与 e 相等的节点,若存在这样的节点,则返回位置,否则返回 0    
    <strong>int LocateElem(LinkList *L,ElemType e)
    { int i=1;
       LinkList *p=L->next;	//p指向开始节点,i置为1  
       while (p!=NULL && p->data!=e) 
      {  p=p->next;  //查找data值为e的节点,其序号为i

	i++;
      }
     if (p==NULL)	//不存在元素值为e的节点,返回0
	return(0);
     else		//存在元素值为e的节点,返回其逻辑序号i
	return(i);
    }</strong>
       本算法的时间复杂度为 O(n)
      8)插入数据元素ListInsert(&L,i,e)
      先在单链表 L 中找到第 i -1 个节点 *p ,若存在这样的节点,将值为 e 的节点 *s 插入到其后。  
  <strong> bool ListInsert(LinkList *&L,int i,ElemType e)
   {  int j=0;
       LinkList *p=L,*s;          //p指向头节点,j置为0
       while (j<i-1 && p!=NULL)	//查找第i-1个节点
      {	j++;
	p=p->next;
      }
      if (p==NULL)	//未找到第i-1个节点,返回false
	return false;
       else		//找到第i-1个节点*p,插入新节点并返回true
     {	s=(LinkList *)malloc(sizeof(LinkList));
	s->data=e;		//创建新节点*s,其data域置为e
	s->next=p->next;	//将*s插入到*p之后
	p->next=s;
	return true;
     }
   }</strong>
      本算法的时间复杂度为 O(n)
     9)删除数据元素ListDelete(&L,i,&e)
     先在单链表 L 中找到第 i -1个节点* p ,若存在这样的节点,且也存在后继节点,则删除该后继节点。    
  <strong> bool ListDelete(LinkList *&L,int i,ElemType &e)
   { int j=0;
      LinkList *p=L,*q;		//p指向头节点,j置为0
      while (j<i-1 && p!=NULL)	//查找第i-1个节点
     {	j++;
  	p=p->next;
     }
    if (p==NULL)	//未找到第i-1个节点,返回false
	return false;
    else		//找到第i-1个节点*p
    {	q=p->next;		//q指向第i个节点
	if (q==NULL)	//若不存在第i个节点,返回false
	   return false;
	e=q->data;
	p->next=q->next;	//从单链表中删除*q节点
	free(q);		//释放*q节点
	return true;	//返回true表示成功删除第i个节点
     }
   }</strong>
     本算法的时间复杂度为 O(1)









 








   

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值