数据结构-线性表

1、什么是线性表?

线性表(Linear List):由同类型元素构成有序序列的线性结构。

表中元素个数称为线性表的长度

线性表没有元素时,称为空表

表起始位置称表头,表结束位置称为表尾

2、线性表的抽象数据类型描述

List MakeEmpty():初始化一个空线性表L;
ElementType FindKth( int K, List L ):根据位序K,返回相应元素 ;
int Find( ElementType X, List L ):在线性表L中查找X的第一次出现位置;
void Insert( ElementType X, int i, List L):在位序i前插入一个新元素X;
void Delete( int i, List L ):删除指定位序i的元素;
int Length( List L ):返回线性表L的长度n。 

3、主要实现方式:顺序存储实现和链式存储实现

4、线性表的顺序存储实现

(1)如何存储

1
2
3
4
5
6
7
//如何存储
typedef  struct
{
     ElementType Data[MAXSIZE];
     int  Last;
}List;
List L,*PtrL;

访问下标为i的元素:L.Data[i]或PtrL->Data[i]

线性表的长度:L.Last+1或者PtrL->Last+1

(2)初始化(建立空的顺序表)

1
2
3
4
5
6
7
List *MakeEmpty()
{
     List *PtrL;
     PtrL = (List *) malloc ( sizeof (List));
     PtrL->Last = -1;
     return  PtrL;
}

 (3)查找

1
2
3
4
5
6
7
8
9
10
11
12
13
int  Find(ElementType X, List *PtrL)
{
     int  i = 0;
     while (i <= PtrL->Last && PtrL->Data[i]!=X)
         i++;
     if  (i > PtrL->Last)
     {
         return  -1;
     } else
     {
         return  i;
     }
}

查找成功的平均比较次数为(n+1)/ 2(第一次比较就找到或者最后一次比较才找到),平均时间性能为O(n)。

(4)插入(第i(1<=i<=n+1)个位置上插入一个值为X的新元素)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//插入
void  Insert(ElementType X,  int  i,List *PtrL)
{
     int  j;
     if  (PtrL->Last==MAXSIZE-1)
     {
         printf ( "表满" );
         return ;
     }
     if  (i < 1 || PtrL->Last+2)
     {
         printf ( "位置不合法" );
         return ;
     }
     for  (j = PtrL->Last; j >= i-1; --j)
     {
         PtrL->Data[j+1]=PtrL->Data[j]; //将ai~an倒序向后移动
     }  
     PtrL->Data[i-1] = X; //插入新元素
     PtrL->Last++; //Last仍指向最后元素
         return ;
}

平均移动次数为n/2,平均时间性能为O(n)。

(5)删除

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//删除
void  Delete( int  i,List *PtrL)
{
     int  j;
     if  (i < 1 || i >PtrL->Last+1)
     {
         printf ( "不存在第%d个元素" ,i );
         return
     }
     for  (j = i; j <= PtrL->Last;++j)
     {
         PtrL->Data[j-1]=PtrL->Data[j]; //将ai+1~an顺序向前移动
     }
     PtrL->Last--;
     return ;
}

平均移动次数为(n-1)/2,平均时间性能为O(n)。

5、线性表的链式存储实现

不要求逻辑上相邻的两个元素物理上也相邻;通过“链”建立起数据元素之间的逻辑关系

插入、删除不需要移动数据元素,只需要修改“链”。

(1)如何存储

1
2
3
4
5
6
7
//如何存储
typedef  struct  Node
{
     ElementType Data;
     struct  Node *Next;
}List;
List L,*PtrL;

(2)求表长

1
2
3
4
5
6
7
8
9
10
11
12
//求表长
int  Length(List *PtrL)
{
     List *p = PtrL; //p指向表的第一个结点
     int  j = 0;
     while (p)
     {
         p = p->Next; //当前p指向第j个结点
         j++;
     }
     return  j;
}

 (3)查找

按照序号查找:FindKth

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
List *FindKth( int  K,List *PtrL)
{
     List *p = PtrL;
     int  i = 1;
     while (p != NULL&&i < k)
     {
         p = p->Next;
         i++;
     }
     if  (i==k)
     {
         return  p; //找到第K个,返回指针
     } else
     {
         return  NULL;
     }
}

按照值查找:Find

1
2
3
4
5
6
7
8
9
10
List *Find(ElementType X,List *PtrL)
{
     List *p = PtrL;
     while (p != NULL && p->Data != X)
     {
         p = p->Next;
 
     }
     return  p;
}

(4)插入

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
List *Insert(ElementType X,  int  i, List *PtrL)
{
     List *p,*s;
     if  (i == 1) //新结点插入在表头
     {
         s = (List *) malloc ( sizeof (List));
         s->Data = X;
         s->Next = PtrL;
         return  s;
     }
     p = FindKth(i-1,PtrL);
     if  (p == NULL)
     {
         printf ( "参数i错误" ); //第i-1个元素不存在,则不能插入
         return  NULL;
     } else
     {
         s = (List *) malloc ( sizeof (List));
         s->Data = X;
         s->Next = p->Next; //新结点插入在第i-1个结点的后面
         p->Next = s;
         return  PtrL;
     }
}

(5)删除(删除链表的第i(1<=i<=n)个位置上的结点)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
List *Delete( int  i,List *PtrL)
{
     List *p,*s;
     if  (i == 1) //删除的结点是第一个结点
     {
         s = PtrL; //s指向第一个结点
         if  (PtrL!=NULL)
         {
             PtrL = PtrL->Next; //从链表中删除
         } else
         {
             return  NULL;
         }
         free (s);
         return  PtrL;
     }
     P = FindKth(i-1, PtrL); //查找第i-1个结点
     if  (p == NULL)
     {
         printf ( "第%d个结点不存在" ,i-1);
         return  NULL;
     } else  if  (p->Next==NULL)
     {
         printf ( "第%d个结点不存在" ,i );
         return  NULL;
     } else
     {
         s = p->Next; //s指向第i个结点
         p->Next = s->Next; //从链表中删除
         free (s)
         return  PtrL;
     }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值