数据结构总结(2.11线性表分类)

线性表分为了顺序存储和链式存储两种:

顺序存储:即将数据结点按逻辑顺序存于一组连续的存储单元

顺序存储的特点:

线性表的逻辑顺序与物理顺序一致

数据元素相邻的位置与计算机的物理位置相同。

即:

a(i)=a(0)+(i-1)*l;l代表长度

此描述与前者相同

其功能函数:

插入:

Code:
  1. Status Insert_SqList(Sqlist *L,int i ,ElemType e)   
  2.  {  
  3.  int j ;   
  4. if  ( i<0||i>L->length-1)   return  ERROR ;   
  5. if  (L->length>=MAX_SIZE)   
  6.    {   
  7.  printf(“线性表溢出!/n”);  return  ERROR ; 
  8.    }   
  9. for  ( j=L->length–1; j>=i-1; --j )   
  10. L->Elem_array[j+1]=L->Elem_array[j];   
  11. /*  i-1位置以后的所有结点后移  */  
  12. L->Elem_array[i-1]=e;    /*  在i-1位置插入结点  */  
  13. L->length++ ;   
  14. return  OK ;     
  15. }   

此算法中的时间复杂程度o=f(i)=(n-i+1)/2

所以时间复杂程度为o(n)

删除:

Code:
  1. ElemType  Delete_SqList(Sqlist *L,int i)   
  2. {  
  3. int  k ;   ElemType  x ;   
  4. if  (L->length==0)   
  5.    {  printf(“线性表L为空!/n”); return ERROR;   
  6.     }    
  7. else if ( i<1||i>L->length )    
  8.    {  printf(“要删除的数据元素不存在!/n”) ;    
  9.   return ERROR ;    
  10.     }   
  11. else     
  12.     {  x=L->Elem_array[i-1] ;   /*保存结点的值*/  
  13. for ( k=i ;  k<L->length ; k++)    
  14.       L->Elem_array[k-1]=L->Elem_array[k];   
  15.              /*  i位置以后的所有结点前移  */  
  16. L->length--;  return (x);   
  17.     }   
  18. }   

此函数的时间复杂程度也为o(n)

定点删除:

Code:
  1. Status  Locate_Delete_SqList(Sqlist *L,ElemType x)   
  2.      /*  删除线性表L中值为x的第一个结点  */  
  3. {    
  4.   int  i=0 , k ;    
  5. while  (i<L->length)      /*查找值为x的第一个结点*/  
  6.   {   if  (L->Elem_array[i]!=x )  i++ ;    
  7. else     
  8.    {  for ( k=i+1; k< L->length; k++)   
  9.            L->Elem_array[k-1]=L->Elem_array[k];    
  10.        L->length--;  break ;    
  11.    }   
  12.   }   
  13. if  (i>L->length)   
  14.   {    printf(“要删除的数据元素不存在!/n”) ;    
  15.    return ERROR ;    
  16.    }   
  17. return  OK;       
  18. }   

此也为o(n)

链式存储:用的任意存储单元存储线性表的数据元素

其由数据域和指针域构成

所以又分成单链表和双向链表

单链表中只有头指针,而双向链表中有尾指针(这个也可以用数组的下标可以实现此功能、在c中的数组都会退化为指针)

其中一种有特点的链表:

循环链表

链式存储的特点:

链表中结点的逻辑顺序和物理顺序不一定相同。(这个就如同一个人进入一栋楼房中找人一样,那一个人就是头指针,而楼房就是存储单元)

循环链表的描述:

Code:
  1. typedef  struct  Lnode   
  2. {   ElemType  data;     /*数据域,保存结点的值 */  
  3. struct   Lnode  *next;      /*指针域*/  
  4. }LNode;        /*结点的类型   
Code:
  1. class linkist   
  2. {   
  3. private:   
  4. elemtype data;   
  5. elemtype  *next;   
  6. public:   
  7. delete();   
  8. insert();   
  9. search();   
  10. locate del();   
  11. }  

此链表中的头指针因为是动态出现的所以为此必须要在使用是申请动态的内存

c:

p=(Lnode*)maclloc(sizeof(Lnode*));

c++:

p=new elemtype

删除时:

free(*p)

delete p

功能函数:

Code:
  1. #define flag 32768
  2. /*因为是int型,所以将32768作为结束*/
  3. LNode  *create_LinkList(void)   
  4.     /*  头插入法创建单链表,链表的头结点head作为返回值  */     
  5. {     
  6.   int data ;   
  7. LNode *head, *p;   
  8. head= (LNode  *) malloc( sizeof(LNode));   
  9. head->next=NULL;       /*  创建链表的表头结点head  */    
  10. while (flag)    
  11.   {   
  12. scanf(“%d”, &data) ;   
  13.   if (data==flag)  break ;   
  14.   p= (LNode  *)malloc(sizeof(LNode));   
  15.   p–>data=data;     /*  数据域赋值  */  
  16.   p–>next=head–>next ;  head–>next=p ;    
  17.        /*  钩链,新创建的结点总是作为第一个结点  */  
  18.   }   
  19. return (head);   
  20. }  

 

 

Code:
  1.   
  2. LNode  *create_LinkList(void)   
  3.      /*  尾插入法创建单链表,链表的头结点head作为返回值  */     
  4. {      
  5. int data ;   
  6. LNode *head, *p, *q;   
  7. head=p=(LNode  *)malloc(sizeof(LNode));    
  8. p->next=NULL;        /*  创建单链表的表头结点head  */  
  9. while (flag)   
  10. {    scanf(“%d”,& data);   
  11. if (data==flag)  break ;   
  12. q= (LNode  *)malloc(sizeof(LNode));    
  13. q–>data=data;     /*   数据域赋值  */  
  14. q–>next=p–>next;  p–>next=q; p=q ;   

 对于单链表,无论是哪种操作,只要涉及到钩链(或重新钩链),如果没有明确给出直接后继,钩链(或重新钩链)的次序必须是“先右后左

Code:
  1. ElemType   Get_Elem(LNode *L , int  i)   
  2. {     
  3.   int j ;   LNode *p;   
  4. p=L->next;  j=1;      /*  使p指向第一个结点  */  
  5. while  (p!=NULL && j<i)   
  6. {   p=p–>next;  j++;  }        /*  移动指针p , j计数  */  
  7. if  (j!=i)  return(-32768) ;   
  8. else      return(p->data);   
  9.  /*   p为NULL 表示i太大;  j>i表示i为0  */  
  10. }   
  11.   
  12. LNode *Locate_Node(LNode *L,int key)   
  13. /*  在以L为头结点的单链表中查找值为key的第一个结点  */    
  14. {    
  15.   LNode *p=L–>next;   
  16. while  ( p!=NULL&& p–>data!=key)    p=p–>next;   
  17. if  (p–>data==key)   return p;   
  18. else     
  19. {    printf(“所要查找的结点不存在!!/n”);    
  20. retutn(NULL);     
  21. }   
  22. }   
  23.   
  24. void  Insert_LNode(LNode *L,int i,ElemType e)   
  25.     /*  在以L为头结点的单链表的第i个位置插入值为e的结点 */    
  26. {   int  j=0;  LNode *p,*q;   
  27. p=L–>next ;   
  28. while  ( p!=NULL&& j<i-1)    
  29. {  p=p–>next;  j++;   }   
  30.   
  31.   
  32.   
  33. if  (j!=i-1)     printf(“i太大或i为0!!/n ”);    
  34. else  
  35. {  q=(LNode *)malloc(sizeof(LNode));   
  36. q–>data=e;   q–>next=p–>next;   
  37. p–>next=q;   
  38. }   
  39. }   
  40.   
  41.   
  42.   
  43. void  Delete_LinkList(LNode *L, int i)   
  44.   /*  删除以L为头结点的单链表中的第i个结点  */    
  45. {  int  j=1;  LNode *p,*q;   
  46. p=L;  q=L->next;   
  47. while  ( p->next!=NULL&& j<i)    
  48. {  p=q;  q=q–>next;  j++;  }   
  49. if  (j!=i)     printf(“i太大或i为0!!/n ”);     
  50. else       
  51. {  p–>next=q–>next;   free(q);    }   
  52. }   
  53.   
  54.   
  55. void  Delete_LinkList(LNode *L,int key)   
  56. /*  删除以L为头结点的单链表中值为key的第一个结点  */    
  57. {     LNode *p=L,  *q=L–>next;   
  58. while  ( q!=NULL&& q–>data!=key)        
  59. {  p=q;  q=q–>next;   }   
  60. if  (q–>data==key)      
  61. {  p->next=q->next;  free(q);   }   
  62. else     
  63. printf(“所要删除的结点不存在!!/n”);   
  64. }    
  65.   
  66. void  Delete_LinkList_Node(LNode *L,int key)   
  67. /*  删除以L为头结点的单链表中值为key的第一个结点  */    
  68. {     LNode *p=L,  *q=L–>next;   
  69. while  ( q!=NULL)   
  70. {  if (q–>data==key)    
  71.      {  p->next=q->next;  free(q);  q=p->next;  }   
  72. else  
  73.      {  p=q;  q=q–>next;   }   
  74. }   
  75. }    
  76.   
  77. void  Delete_Node_value(LNode *L)   
  78. /*  删除以L为头结点的单链表中所有值相同的结点  */    
  79. {     LNode *p=L->next, *q, *ptr;    
  80. while  ( p!=NULL)   /*  检查链表中所有结点  */    
  81. {   *q=p, *ptr=p–>next;   
  82. /*  检查结点p的所有后继结点ptr  */  
  83. while (ptr!=NULL)   
  84.      {  if (ptr–>data==p->data)    
  85.             {  q->next=ptr->next;  free(ptr);     
  86.                 ptr=q->next;  }   
  87.         else  {  q=ptr;  ptr=ptr–>next;   }   
  88.      }   
  89. p=p->next ;   
  90. }   
  91. }    
  92.   
  93.   
  94.   
  95. LNode  *Merge_LinkList(LNode *La, LNode *Lb)   
  96.       /*  合并以La, Lb为头结点的两个有序单链表   */  
  97. {    LNode *Lc,  *pa ,  *pb ,  *pc, *ptr ;   
  98. Lc=La ;  pc=La  ;    pa=La->next ;  pb=Lb->next  ;   
  99.  while (pa!=NULL    && pb!=NULL)   
  100.  {  if  (pa->data<pb->data)   
  101.     {   pc->next=pa ;  pc=pa ;   pa=pa->next  ;   }   
  102. /*  将pa所指的结点合并,pa指向下一个结点  */  
  103. if  (pa->data>pb->data)   
  104.     {   pc->next=pb ;  pc=pb ;   pb=pb->next  ;   }   
  105. /*  将pa所指的结点合并,pa指向下一个结点  */  
  106. if  (pa->data==pb->data)   
  107.     {   pc->next=pa ;  pc=pa ;   pa=pa->next  ;    
  108.          ptr=pb ; pb=pb->next ; free(ptr) ;   }   
  109. /*  将pa所指的结点合并,pb所指结点删除  */  
  110. }   
  111.  if  (pa!=NULL)  pc->next=pa ;   
  112. else   pc->next=pb ;     /*将剩余的结点链上*/  
  113. free(Lb) ;   
  114. return(Lc) ;   
  115. }   

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值