当前位置:文档之家› 数据结构 第三章课后习题及总结

数据结构 第三章课后习题及总结

数据结构第三章
T1223-3-28朱俊杰
一、原理讨论题:
1、顺序存储的三个优点:
1思路和实现都比较简单,容易理解。

2不用为表示结点间的逻辑关系而增加额外的存储空间。

3顺序表具有按元素序号随机访问的特点。

顺序比链式节约空间。

是因为链式结构每一个节点都有一个指针存储域。

顺序支持随机存取,方便操作
链式的要比顺序的方便
2、线性结构
3、顺序存储和链式存储
4、判断是否为空、求顺序表长度、遍历顺序表所有元素、读取一个结点、修改一个结点、插入一个结点、删除一个结点、顺序表所有元素反转。

二、理论基本题:
1
2
3
…i-1 i
i+1 …n

1
2
3
…i-1 i
i+1 …n

序号内容序号内容
插入前插入后
图2-3 顺序表中插入元素前后状态
0 1 2 3 … i-1 i i+1 … n-1 …
0 1 2 3 … i-1 i i+1 … n … 序号 内容
序号 内容 删除前
删除后
图2-4 顺序表中删除元素前后状态
图2-6 单链表的逻辑表示
线性链表
线性链表是具有链接存储结构的线性表,它用一组地址任意的存储单元存放线性表中的数据元素,逻辑上相邻的元素在物理上不要求也相邻,不能随机存取。

一般用结点描述:结点(表示数据元素)=数据域(数据元素的映象)+ 指针域(指示后继元素存储位置)。

概念
在链式存储结构中,存储数据结构的存储空间可以不连续,各数据结点的存储顺序与数据元素之间的逻辑关系可以不一致,而数据元素之间的逻辑关系是由指针域来确定的。

链式存储方式即可以用于表示线性结构,也可用于表示非线性结构。

一般来说,在线性表的链式存储结构中,各数据结点的存储符号是不连续的,并且各结点在存储空间中的位置关系与逻辑关系也不一致。

对于线性链表,可以从头指针开始,沿各结点的指针扫描到链表中的所有结点。

线性表的查询操作在链表中的实现:
基本操作为: 使指针p始终指向线性表中第j个数据元

Status GetElem_L(LinkList L, int i, ElemType &e)// L 为带头结点的单链表的头指针。

当线性表中存在第i个元素时,则将第i个数据元素的值赋给e并返回OK,否则返回ERROR
{p = L->next; j = 1; // 初始化,p指向第一个结点,j为计数器
while (p && j){ //顺指针向后查找,直到p指向第i个元素或p为空
p = p->next; ++j;
if ( !p || j>i ) continue; // 第i个元素不存在
e = p->data; // 取第i个元素
return OK; }
}
直到第i个数据,才退出continue循环,并得到e=p->data,放回ok。

线性表的插入操作在链表中的实现:
基本操作为: 找到线性表中第i-1个结点,修改其指向后继的指针
有序对<ai-1, ai> 改变为<ai-1, e> 和<e, ai>
Status ListInsert_L(LinkList L, int i, ElemType e) {
// 在带头结点的单链表L中第i个数据元素之前插入数据元素e
p = L; j = 0;
if (!p|| j > i-1) return ERROR; // i小于1或者大于表长while (p && j < i-1)
{ p = p->next; ++j;
} // 寻找第i-1个结点
2
s =
(LinkList) malloc (sizeof (LNode)); // 生成新结点
s->data = e; s->next = p->next; // 插入L中
p->next = s;
return OK;
} // LinstInsert_L算法的时间复杂度
为:O(ListLength(L))
|带头结点的单链线性表编辑
在线性表的链接存储中,为了方便在表头插入和删除结点的操作,经常在表头结点(存储第一个元素的结点)的前面增加一个结点,称之为头结点或表头附加结点。

这样原来的表头指针由指向第一个元素的结点改为指向头结点,头结点的数据域为空,头结点的指针域指向第一个元素的结点。

定义一个带头结点的线性链表类型:
typedef struct LNode // 结点类型
{
char data;
struct LNode *next;
} *Link,*Position;
typedef struct // 链表类型
{ Link head, tail; // 指向头结点和最后一个结点
int len; // 指示链表长度
Link current; // 指向当前访问的结点的指针,初始位置指向头结点
}LinkList;
Status MakeNode( Link &p, ElemType e );
// 分配由p指向的值为e的结点,并返回OK;若分配失败,则返回ERROR
void FreeNode( Link &p ); // 释放p所指结点创建带头结点的单链线性表:
void CreateList_L(LinkList&L, int n) // 逆位序输入n个元素的值,建立带表头结点的、//单链线性表L。

{ L = (LinkList) malloc (sizeof (LNode));
L->next = NULL; // 先建立一个带头结点的单链表
for (i = n; i > 0; --i) {
p = (LinkList) malloc (sizeof (LNode)); // 生成新结点
scanf(“%d”,&p->data); // 输入元素值
p->next = L->next; L->next = p; // 插入到表头
}
}
本章的收获、体会:
malloc函数其作用是在动态存储区中分配一个长度为size 的连续空间。

此函数返回值是一个指向分配域起始地址的指
针(基类型为void).如果此函数未能分配成功地执行(例如内存空间不足)则返回空指针(NULL)。

calloc函数其作用是在内存的动态区存储中分配n个长度为size的连续空间,函数返回一个指向分配起始域地址的指针;如果分配不成功,返回NULL
free函数其作用是释放由P指向的内存区,使这部分内存区能被其它变量使用。

P是最近一次调用的calloc或malloc 函数时返回的值。

free无返回值。

define宏定义
线性表的两类不同的存储结构,不受空间限制,在节点的插入、删除方便,不用大量移动数据,数据结构中的线性表、顺序表和链表之间的特点和区别,数组就是顺序表,
单链表就是链表,可以线性的存贮数据,顺序表中的元素是按其物理位置排列的,链表是通过指针来描述其逻辑位置的,链表是指针与型结构体类型的一种结合体,链表的每一个节点都应该包含两个部分:节点数据和指向下一节点的指针。

因为下一节点具有与该节点相同的结构,所以链表节点的类型定义时,需要引用正在定义的类型的本身,与数组相比,链表在插入和删除节点时比的插入和删除要简单,开销更小,但链表不可随机访问它的节点,只能通过指向链表表头的指针顺序访问相应的节点。

相关主题