当前位置:
文档之家› 数据结构C语言版第二章课件严蔚敏
数据结构C语言版第二章课件严蔚敏
3. ai是第i个元素,称i为数据元素ai在线性表中的位序 。
4.
例子: 英文字母表(A, B, …, Z) ; 车辆登记表 。
5. 线性表的特点
同一性:线性表由同类数据元素组成,每一 个ai必须属于同一数据对象。 有穷性:线性表由有限个数据元素组成, 表 长度就是表中数据元素的个数。
有序性:线性表中相邻数据元素之间存在着 序偶关系<ai, ai+1>。
假设线性表中有n个元素,每个元素占k 个单元,第一个元素的地址为loc(a1),则可 以通过如下公式计算出第i个元素的地址 loc(ai):
loc(ai) =loc(a1)+(i-1)×k
其中loc(a1)称为基地址。
2. 顺序表的特点:
逻辑结构中相邻的数据元素在存储结构中 仍然相邻。
线性表的顺序存储结构是一种随机存取 的存储结构。
} q = &(L.elem[i-1]); for( p = &(L.elem[L.length-1]; p>=q; --p)
*(p+1) = *p; *q = e; ++L.length; return OK;
}
// 越界处理
if ( L.length >= L.listsize ) { newbase = ( ElemType * ) realloc ( L.elem , ( L.listsize + LISTINCREMENT ) * sizeof(ElemType) ); if ( ! newbase ) exit(OVERFLOW) ; L.elem = newbase ; L.listsize += LISTINCREMENT ;
}
算法时间复杂度:
时间主要花在移动元素上,而移动元素的个数取决 于插入元素位置。
i=1,需移动 n 个元素; i=n+1,需移动 0 个元素; i=i,需移动 n – i +1 个元素;
假设pi是在第 i 个元素之前插入一个新元素的概率
则长度为 n 的线性表中插入一个元素所需移动元
n+1
素次数的期望值为: Eis = ∑ pi (n – i + 1)
if( (i<1) || (i>L.length) ) return ERROR;
p = &(L.elem[i-1]); e = *p; q = L.elem+L.length-1; for( ++p; p<=q; ++p)
*(p-1) = *p; --L.length; return OK;
}
算法时间复杂度:
4. 顺序表上基本运算的实现
初始化 Status InitList_Sq ( SqList &L)
{ L.elem = (ElemType * )malloc(LIST_INIT_SIZE* sizeof(ElemType)); if(!L.elem) exit(OVERFLOW); L.length = 0; L.listsize = LIST_INIT_SIZE; return OK;
顺序表中插入元素
插入 Status ListInsert_Sq (SqList &L, int i, ElemType e) {
if( (i<1) || (i>L.length+1) ) return ERROR;
if(L.length >= L.listsize){ realloc(…); ….; // 越界处理 ;
3. 顺序表的描述:
typedef struct
{
ElemType *elem; //ElemType elem[MAXSIZE];
int
length; //当前长度
int
listsize; //分配的存储容量
} SqList;
typedef # ElemType; #为根据具体问题确定的数据类型 typedef int Status;
时间主要花在移动元素上,而移动元素的个数取决 于删除元素位置。
i=1,需移动n - 1个元素; i=n,需移动0个元素; i=i,需移动n – i 个元素;
假设qi是删除第 i 个元素的概率
则长度为 n 的线性表中删除一个元素所需移动元
n
素次数的期望值为: Edl = ∑ qi (n – i)
i=1
6. 线性表的基本运算
初始化 InitList(&L) 建立一个空表。 求表长 ListLength(L) 返回线性表的长度。 读表元素 GetElem(L, i, &e) 用e返回L中第i个数据元素的 值。 定位 LocateElem(L, e, compare()) 返回满足关系的数据元 素的位序。 插入 ListInsert (&L, i, e) 在L中第i个位置之前插入新的数 据元素e,线性表的长度增1。 删除 ListDelete (&L, i, & e) 删除L的第i个位置上的数据元 素e,线性表的长度减1。 输出 ListDisplay (L) 按前后次序输出线性表的所有元素。
O(ListLength(La)+ListLength(Lb))
例,La = ( 3, 5, 8 ) Lb = ( 2, 6, 8, 9, 15 )
构造 Lc = ( 2, 3, 5, 6, 8, 8, 9, 15 )
首先,La_len = 3;Lb_len = 5;
La
i
3
i
5
i
8
i
Lb
Lc
2
j
(a) 带头结点的空单链表
a1
a2
… an
(b) 带头结点的单链表
单链表存储结构描述:
typedef struct LNode {
ElemType data; struct LNode *next; }LNode, *LinkList;
单链表基本运算实现 (1)初始化线性表InitList(L) 该运算建立一个空的单链表,即创建一个头结点。
if(*pa<=*pb) *pc++ = *pa++; else *pc++ = *pb++; } while(pa<=pa_last) *pc++ = *pa++; while(pb<=pb_last) *pc++ = *pb++; }
顺序表的基础要点:
1. 无需为表示元素间的逻辑关系而增加额外的存储 空间,存储密度大(100%);
2.3 线性表的链式表示和实现
线性表链式存储结构的特点: 用一组任意的存储单元存储线性表的元素,不 要求逻辑上相邻的元素在物理位置上也相邻; 插入删除时不需移动大量元素; 失去顺序表可随机存取的优点。
1. 线性链表(单链表) 结点:数据元素的存储映象。
数据域
指针域
data next
数据域用来存储结点的值;指针域用来存储数 据元素的直接后继的地址(或位置)。
练习1:两个线性表LA和LB分别表示两个集合A和B, 现求一个新的集合A=A∪B。
void union( List &La, List Lb) {
La_len = ListLength(La); Lb_len = ListLength(Lb); for( i=1; i<=Lb_len; i++){
void InitList(LinkList &L) {
L=(LinkList)malloc(sizeof(LNode)); /*创建头结点*/
L->next=NULL; }
(2)销毁线性表DestroyList(L) 释放单链表L占用的内存空间。即逐一释放全部结点 的空间。 void DestroyList(LinkList L) { LinkList p=L, q=p->next;
i=1
设在任何位置插入元素等概率, pi =
1 n+1
Eis =
1
n+1
∑ (n – i + 1) =
n+1 i=1
n 2
O(n)
顺序表的删除:删除第5个元素, 图 顺序表中删除元素
删除 Status ListDelete_Sq (SqList &L, int i, ElemType &e) {
2
6
j
3
8
j
5
9
j
6
15
j
8j8源自算法结束!915
2.2 线性表的顺序表示和实现
1. 顺序表:
存储地址 内存空间状态 逻辑地址
按顺序存 储方式构
lo c(a1) lo c(a1)+ k
a1
1
a2
2
…
…
造的线性
表。
lo c(a1)+ (i- 1)k
ai
i
…
…
…
…
lo c(a1)+ (n- 1)k
an
n 空闲
GetElem(Lb, i, e); if(!LocateElem(La, e, equal))
ListInsert(La, ++La_len, e); } }
O(ListLength(La)×ListLength(Lb))
练习2: 两个线性表LA和LB中的数据元素按值非递
减有序排列,现将LA和LB归并为一个新的线性 表,LC中的数据元素仍按值非递减有序排列。
设删除任何位置的元素等概率, qi =