【数据结构第二周】线性表知识点整理
1、什么是线性表?
线性表(Linear List):由同类型元素构成有序序列的线性结构。
表中元素个数称为线性表的长度
线性表没有元素时,称为空表
表起始位置称表头,表结束位置称为表尾
2、线性表的抽象数据类型描述
List MakeEmpty():初始化一个空线性表L;
ElementType FindKth( int K, List L ):根据位序K,返回相应元素 ;
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; } } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步