标签:
(1) 线性表的定义
线性表(List):零个或多个数据元素的有限序列。
(2) 线性表的抽象数据类型
ADT 线性表(List)
Data
线性表的数据对象集合为{a1,a2,...,an},每个元素的类型均为DataType。其中,除第一个元素a1外,每个元素有且仅有一个直接前驱元素,除最后一个元素an外,每一个元素有且只有一个后继元素。数据元素间的关系是一对一的关系。
Operation
initList(&L):初始化操作,建立一个空的线性表L。
listEmpty(L):若线性表为空,返回true,否则返回false。
clearList(L):将线性表清空。
getElem(L,i,&e):将线性表L中的第i个位置元素值返回给e。
locateElem(L,e):在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素在表中序号表示成功;否则,返回0表示失败。
listInsert(&L,i,e):在线性表L中的第i位置插入新元素e。
listDelete(&L,i,&e):删除第i位置的元素,并用e返回其值。
listLength(L):返回线性表L的元素个数。
endADT
(1) 顺序存储定义
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。
(2) 线性表的顺序存储结构代码描述
1 #define LIST_INIT_SIZE 100 // 线性表存储空间的初始分配量 2 #define LISTINCREMENT 10 // 线性表存储空间的分配增量 3 4 typedef struct 5 { 6 ElemType *elem; // 存储空间基址 7 int length; // 当前长度 8 int listsize; // 当前分配的存储容量 9 }SqList;
(3) 地址计算方法
LOC(ai+1) = LOC(ai) + c
LOC(ai) = LOC(a1) + (i - 1) * c
(4) 顺序表的初始化
1 Status initSqList(SqList &L) 2 { 3 L.elem = (ElemType*) malloc (sizeof(ElemType) * LIST_INIT_SIZE); 4 if (!L.elem) return ERROR; // 存储空间分配失败 5 L.length = 0; // 空表长度为0 6 L.listsize = LIST_INIT_SIZE; // 初始存储容量 7 return OK; 8 }
(5) 顺序表的插入操作
插入算法的思路:
参考代码如下:
1 Status insertSqList(SqList &L, int i, ElemType e) 2 { 3 if (i < 1 || i > L.length + 1) return ERROR; // i值不合法 4 if (L.length == L.listsize) // 当前存储空间已满 5 { 6 ElemType *newbase = (ElemType *) realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType)); 7 if (!newbase) return ERROR; // 存储分配失败 8 L.elem = newbase; // 新基址 9 L.listsize += LISTINCREMENT; // 增加存储容量 10 } 11 ElemType *q = &(L.elem[i - 1]), *p = &(L.elem[L.length - 1]); // q为插入位置 12 for (p; p >= q; --p) // 插入位置及之后的元素右移 13 *(p + 1) = *p; 14 *q = e; // 插入e 15 ++L.length; // 表长加1 16 return OK; 17 }
(6) 顺序表的删除操作
删除操作的算法思路:
参考代码如下:
1 Status deleteSqList(SqList &L, int i, ElemType &e) 2 { 3 if (i < 1 || i > L.length) return ERROR; // i值不合法 4 ElemType *p = &(L.elem[i-1]), *q = &(L.elem[L.length-1]); // p为被删除元素的位置 5 e = *p; // 被删除元素的值赋给e 6 for (p; p < q; ++p) // 被删元素之后的元素左移 7 *p = *(p+1); 8 --L.length; // 表长减1 9 return OK; 10 }
(7) 线性表顺序存储结构的优缺点
优点:
缺点:
(1) 单链表的定义
为了表示每个数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其自身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。我们把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称做指针或链。这两部分信息组成数据元素ai的存储映像,称为结点(Node)。
n个结点(ai的存储映像)链结成一个链表,即为线性表(a1,a2,...,an)的链式存储结构,因为此链表的每个结点中只包含一个指针域,所以叫做单链表。
(2) 头指针与头结点
头指针:
头结点:
(3) 线性表的链表存储结构代码描述
1 typedef struct LNode 2 { 3 ElemType data; 4 struct LNode *next; 5 } LNode, *LinkList;
(4) 单链表的读取
获得单链表第i个数据的算法思路:
参考代码如下:
1 Status getElemLinkList(LinkList L, int i, ElemType &e) 2 { 3 int j = 1; 4 LinkList p = L->next; 5 while (p && j < i) // 寻找第i个结点 6 { 7 p = p->next; 8 ++j; 9 } 10 if (!p || j > i) return ERROR; //第i个元素不存在 11 e = p->data; 12 return OK; 13 }
(5) 单链表的插入与删除
单链表第i个数据插入结点的算法思路:
参考代码如下:
1 Status insertLinkList(LinkList &L, int i, ElemType e) 2 { 3 int j = 1; 4 LinkList p = L; 5 while (p && j < i) // 寻找第i个结点 6 { 7 p = p->next; 8 ++j; 9 } 10 if (!p || j > i) return ERROR; // i值不合法 11 LinkList s = (LinkList) malloc (sizeof(LNode)); // 生成新结点 12 s->data = e; 13 s->next = p->next; 14 p->next = s; 15 return OK; 16 }
单链表第i个数据删除结点的算法思路:
参考代码如下:
1 Status deleteLinkList(LinkList &L, int i, ElemType &e) 2 { 3 int j = 1; 4 LinkList p = L; 5 while (p->next && j < i) // 遍历寻找第i个元素 6 { 7 p = p->next; 8 ++j; 9 } 10 if (!(p->next) || j > i) return ERROR; // i值不合法 11 LinkList q = p->next; 12 p->next = q->next; 13 e = q->data; // 将结点q中的数据赋给e 14 free(q); // 让系统回收此结点,释放内存 15 return OK; 16 }
(6) 单链表的整表创建
单链表整表创建算法思路:
实现算法的代码如下所示:
1 void createLinkList(LinkList &L, int n) // 头插法 2 { 3 L = (LinkList) malloc (sizeof(LNode)); 4 L->next = NULL; 5 for (int i = 0; i < n; ++i) 6 { 7 LinkList p = (LinkList) malloc (sizeof(LNode)); // 生成新结点 8 ElemType e; 9 scanf("%d", &e); // 输入元素值 10 p->data = e; 11 p->next = L->next; // 插入到表头 12 L->next = p; 13 } 14 }
这段代码里,我们其实用的是插队的办法,就是始终让新结点在第一的位置。这种算法简称为头插法。可事实上,我们还是可以不这样做,指新结点放都放到最后,这才是正常思维,这种算法称之为尾插法。实现代码如下所示:
1 void createLinkList(LinkList &L, int n) // 尾插法 2 { 3 L = (LinkList) malloc (sizeof(LNode)); 4 LinkList q = L; 5 for (int i = 0; i < n; ++i) 6 { 7 LinkList p = (LinkList) malloc (sizeof(LNode)); // 生成新结点 8 ElemType e; 9 scanf("%d", &e); // 输入元素值 10 p->data = e; 11 q->next = p; // 插入到表尾 12 q = p; 13 } 14 q->next = NULL; // 表示当前链表结束 15 }
(7) 单链表的整表删除
单链表整表删除算法思路如下:
参考代码如下所示:
1 Status clearLinkList(LinkList &L) 2 { 3 LinkList p = L->next, q; // p指向第一个结点 4 while (p) // 没到表尾 5 { 6 q = p->next; 7 free(p); 8 p = q; 9 } 10 L->next = NULL; // 头结点指针域为空 11 return OK; 12 }
(8) 单链表结构与顺序存储结构优缺点
存储分配方式:
时间性能:
空间性能:
标签:
原文地址:http://www.cnblogs.com/xiaoxxmu/p/5582374.html