线性表分为了顺序存储和链式存储两种:
顺序存储:即将数据结点按逻辑顺序存于一组连续的存储单元内
顺序存储的特点:
线性表的逻辑顺序与物理顺序一致
数据元素相邻的位置与计算机的物理位置相同。
即:
a(i)=a(0)+(i-1)*l;l代表长度
此描述与前者相同
其功能函数:
插入:
- Status Insert_SqList(Sqlist *L,int i ,ElemType e)
- {
- int j ;
- if ( i<0||i>L->length-1) return ERROR ;
- if (L->length>=MAX_SIZE)
- {
- printf(“线性表溢出!/n”); return ERROR ;
- }
- for ( j=L->length–1; j>=i-1; --j )
- L->Elem_array[j+1]=L->Elem_array[j];
- /* i-1位置以后的所有结点后移 */
- L->Elem_array[i-1]=e; /* 在i-1位置插入结点 */
- L->length++ ;
- return OK ;
- }
此算法中的时间复杂程度o=f(i)=(n-i+1)/2
所以时间复杂程度为o(n)
删除:
- ElemType Delete_SqList(Sqlist *L,int i)
- {
- int k ; ElemType x ;
- if (L->length==0)
- { printf(“线性表L为空!/n”); return ERROR;
- }
- else if ( i<1||i>L->length )
- { printf(“要删除的数据元素不存在!/n”) ;
- return ERROR ;
- }
- else
- { x=L->Elem_array[i-1] ; /*保存结点的值*/
- for ( k=i ; k<L->length ; k++)
- L->Elem_array[k-1]=L->Elem_array[k];
- /* i位置以后的所有结点前移 */
- L->length--; return (x);
- }
- }
此函数的时间复杂程度也为o(n)
定点删除:
- Status Locate_Delete_SqList(Sqlist *L,ElemType x)
- /* 删除线性表L中值为x的第一个结点 */
- {
- int i=0 , k ;
- while (i<L->length) /*查找值为x的第一个结点*/
- { if (L->Elem_array[i]!=x ) i++ ;
- else
- { for ( k=i+1; k< L->length; k++)
- L->Elem_array[k-1]=L->Elem_array[k];
- L->length--; break ;
- }
- }
- if (i>L->length)
- { printf(“要删除的数据元素不存在!/n”) ;
- return ERROR ;
- }
- return OK;
- }
此也为o(n)
链式存储:用的任意存储单元存储线性表的数据元素
其由数据域和指针域构成
所以又分成单链表和双向链表
单链表中只有头指针,而双向链表中有尾指针(这个也可以用数组的下标可以实现此功能、在c中的数组都会退化为指针)
其中一种有特点的链表:
循环链表
链式存储的特点:
链表中结点的逻辑顺序和物理顺序不一定相同。(这个就如同一个人进入一栋楼房中找人一样,那一个人就是头指针,而楼房就是存储单元)
循环链表的描述:
- typedef struct Lnode
- { ElemType data; /*数据域,保存结点的值 */
- struct Lnode *next; /*指针域*/
- }LNode; /*结点的类型
- class linkist
- {
- private:
- elemtype data;
- elemtype *next;
- public:
- delete();
- insert();
- search();
- locate del();
- }
此链表中的头指针因为是动态出现的所以为此必须要在使用是申请动态的内存
c:
p=(Lnode*)maclloc(sizeof(Lnode*));
c++:
p=new elemtype
删除时:
free(*p)
delete p
功能函数:
- #define flag 32768
- /*因为是int型,所以将32768作为结束*/
- LNode *create_LinkList(void)
- /* 头插入法创建单链表,链表的头结点head作为返回值 */
- {
- int data ;
- LNode *head, *p;
- head= (LNode *) malloc( sizeof(LNode));
- head->next=NULL; /* 创建链表的表头结点head */
- while (flag)
- {
- scanf(“%d”, &data) ;
- if (data==flag) break ;
- p= (LNode *)malloc(sizeof(LNode));
- p–>data=data; /* 数据域赋值 */
- p–>next=head–>next ; head–>next=p ;
- /* 钩链,新创建的结点总是作为第一个结点 */
- }
- return (head);
- }
- LNode *create_LinkList(void)
- /* 尾插入法创建单链表,链表的头结点head作为返回值 */
- {
- int data ;
- LNode *head, *p, *q;
- head=p=(LNode *)malloc(sizeof(LNode));
- p->next=NULL; /* 创建单链表的表头结点head */
- while (flag)
- { scanf(“%d”,& data);
- if (data==flag) break ;
- q= (LNode *)malloc(sizeof(LNode));
- q–>data=data; /* 数据域赋值 */
- q–>next=p–>next; p–>next=q; p=q ;
对于单链表,无论是哪种操作,只要涉及到钩链(或重新钩链),如果没有明确给出直接后继,钩链(或重新钩链)的次序必须是“先右后左
- ElemType Get_Elem(LNode *L , int i)
- {
- int j ; LNode *p;
- p=L->next; j=1; /* 使p指向第一个结点 */
- while (p!=NULL && j<i)
- { p=p–>next; j++; } /* 移动指针p , j计数 */
- if (j!=i) return(-32768) ;
- else return(p->data);
- /* p为NULL 表示i太大; j>i表示i为0 */
- }
- LNode *Locate_Node(LNode *L,int key)
- /* 在以L为头结点的单链表中查找值为key的第一个结点 */
- {
- LNode *p=L–>next;
- while ( p!=NULL&& p–>data!=key) p=p–>next;
- if (p–>data==key) return p;
- else
- { printf(“所要查找的结点不存在!!/n”);
- retutn(NULL);
- }
- }
- void Insert_LNode(LNode *L,int i,ElemType e)
- /* 在以L为头结点的单链表的第i个位置插入值为e的结点 */
- { int j=0; LNode *p,*q;
- p=L–>next ;
- while ( p!=NULL&& j<i-1)
- { p=p–>next; j++; }
- if (j!=i-1) printf(“i太大或i为0!!/n ”);
- else
- { q=(LNode *)malloc(sizeof(LNode));
- q–>data=e; q–>next=p–>next;
- p–>next=q;
- }
- }
- void Delete_LinkList(LNode *L, int i)
- /* 删除以L为头结点的单链表中的第i个结点 */
- { int j=1; LNode *p,*q;
- p=L; q=L->next;
- while ( p->next!=NULL&& j<i)
- { p=q; q=q–>next; j++; }
- if (j!=i) printf(“i太大或i为0!!/n ”);
- else
- { p–>next=q–>next; free(q); }
- }
- void Delete_LinkList(LNode *L,int key)
- /* 删除以L为头结点的单链表中值为key的第一个结点 */
- { LNode *p=L, *q=L–>next;
- while ( q!=NULL&& q–>data!=key)
- { p=q; q=q–>next; }
- if (q–>data==key)
- { p->next=q->next; free(q); }
- else
- printf(“所要删除的结点不存在!!/n”);
- }
- void Delete_LinkList_Node(LNode *L,int key)
- /* 删除以L为头结点的单链表中值为key的第一个结点 */
- { LNode *p=L, *q=L–>next;
- while ( q!=NULL)
- { if (q–>data==key)
- { p->next=q->next; free(q); q=p->next; }
- else
- { p=q; q=q–>next; }
- }
- }
- void Delete_Node_value(LNode *L)
- /* 删除以L为头结点的单链表中所有值相同的结点 */
- { LNode *p=L->next, *q, *ptr;
- while ( p!=NULL) /* 检查链表中所有结点 */
- { *q=p, *ptr=p–>next;
- /* 检查结点p的所有后继结点ptr */
- while (ptr!=NULL)
- { if (ptr–>data==p->data)
- { q->next=ptr->next; free(ptr);
- ptr=q->next; }
- else { q=ptr; ptr=ptr–>next; }
- }
- p=p->next ;
- }
- }
- LNode *Merge_LinkList(LNode *La, LNode *Lb)
- /* 合并以La, Lb为头结点的两个有序单链表 */
- { LNode *Lc, *pa , *pb , *pc, *ptr ;
- Lc=La ; pc=La ; pa=La->next ; pb=Lb->next ;
- while (pa!=NULL && pb!=NULL)
- { if (pa->data<pb->data)
- { pc->next=pa ; pc=pa ; pa=pa->next ; }
- /* 将pa所指的结点合并,pa指向下一个结点 */
- if (pa->data>pb->data)
- { pc->next=pb ; pc=pb ; pb=pb->next ; }
- /* 将pa所指的结点合并,pa指向下一个结点 */
- if (pa->data==pb->data)
- { pc->next=pa ; pc=pa ; pa=pa->next ;
- ptr=pb ; pb=pb->next ; free(ptr) ; }
- /* 将pa所指的结点合并,pb所指结点删除 */
- }
- if (pa!=NULL) pc->next=pa ;
- else pc->next=pb ; /*将剩余的结点链上*/
- free(Lb) ;
- return(Lc) ;
- }