《数据结构》(C语言版,严蔚敏 编著) 考前巩固

三、综合题

8.直接插入排序 和 简单选择排序 算法的执行过程

  1. 直接插入排序
void InsertSort(SqList &L){
//对顺序表L作直接插入排序
	for( i = 2; i <= L.length; ++i ){
		if(	LT( L.r[i].key, L.r[i-1].key )){
			L.r[0] = L.r[i];					//复制为哨兵
			
			L.r[i] = L.r[i-1];					//将 i-1 记录后移
			for( j = i - 2; LT( L.r[0].key, L.r[j].key ); --j){
				L.r[j+1] = L.r[j];				//将 i-1 之前的记录后移
			}
			L.r[j+1] = L.r[0];					//插入到正确位置
		}
	}
}

直接插入排序的简单版,利于理解,但效率次于上述代码

void InsertSort(SqList &L){
	for( i = 2; i <= T.length; i++ ){
		if(L.[i] < L.[i-1]){
			L.[0] = L.[i];						//复制为哨兵
			
			int j = i;
			for( ; L.[j-1] > L.[0]; j-- ){		//从i-1起,进行记录后移
				L.[j] = L.[j-1];
			}
			L.[j] = L.[0];						//插入到正确位置
		}
	}
}
  1. 简单选择排序
void SelectSort(SqList &L){
	for( i = 1; i < L.length; i++ ){
		j = SelectMinKey(L,i);
		if( i != j ){							//在L.r[i...L.length]中选择 key 最小的记录
			L.r[i]←→L.r[j];
		}
	}
}

四、算法题

1.线性链表 Create

  • 逆序建立(头插法):先建立头节点,再从后往前添加元素。
void List_Create(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(&p->data);
		p->next = L->next;
		L->next = p;
	}
}
  • 顺序建立(尾插法):
void CreateList2(LinkList& L,int n){	
	L = (LinkList)malloc(sizeof(LNode)); 
	L->next = NULL;
	q = L;
	for( i = 1; i <= n; i++ ){
		p = (LinkList)malloc(sizeof(LNode));
		scanf(&p->data);
		q->next = p;
		q = q->next;
	}
	p->next = NULL;//next域置空。
}

2.线性链表 Delete

Status List_Delete(LinkList &L,int i,ElemType &e){
//在单链表L中,删除第 i 个元素,并由 e 返回其值。
	p = L;
	j = 0;
	while( p->next && j < i-1 ){//让 p 指向待删除结点的前驱,即 i-1
		p = p->next;
		++j;
	}
	if( !( p->next ) || j > i-1 ){//p 指向了最后一个元素 || j 超出 待删除的位置i (在数组中的位置i-1)
		return ERROR;
	}
	q = p->next;
	p->next = q->next;
	e = q->data;
	free(q);
	return OK;
}

free(q);:由系统回收一个 LNode 型的结点,回收后的空间可以备作再次生成结点时使用。

3.线性链表 Insert

Status List_insert(LinkList &L,int i,ElemType e){
//在单链表L中,插入元素 e 到第 i 个位置。原第 i 个元素的位置变为 i+1。 
	p = L;
	j = 0;
	while( p && j < i-1 ){//查找第 i-1 个值
		p = p->next;
		++j; 
	}
	if( !p || j > i-1 ){//指针 p 为空 || j 超出 目的插入位置i (在数组中的下标i-1)
		return ERROR;
	}
	s = (LinkList)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}

s = (LinkList)malloc(sizeof(LNode));:由系统生成一个 LNode 型的结点,同时将该结点的起始位置赋给指针变量 s

4.求二叉树的深度

int BiTreeDepth(BiTree T){
	if (!T){
		return 0;
	}else
	{
		l = BiTreeDepth(T->lchild);
		r = BiTreeDepth(T->rchild);
		return (l > r) ? (l + 1) : (r + 1);
	}
}

5. 折半查找算法 p220

int Search_Bin(SSTable ST, KeyType key){
	low = 1;
	high = ST.length;
	while(low <= high){
		mid = (low + high) / 2;
		if( EQ( key,ST.elem[mid].key ) ){//找到带查找元素
			return mid;
		}else if( LT( key,ST.elem[mid].key ) ){
			high = mid -1;
		}else{
			low = mid +1;
		}
	}
	return 0;
}

6.统计二叉树中叶子结点的个数

int CountLeaf(BiTree T,int &count){
	if(T){
		if( !T->lchild && !T->rchild ){
			count++;
		}
		CountLeaf(T->lchild, count);
		CountLeaf(T->rchild, count);
	}
}

叶子结点的特征是左孩子和右孩子都为空,若有一个不为空,那就再遍历一次。

7.循环队列的入队算法 p65

Status EnQueue(SqQueue &Q, QElemType e){
// 插入新的队尾元素 e
	if( ( Q.rear+1 ) % MAXQSIZE == Q.front ){
		return ERROR;
	}
	Q.base[Q.rear] = e;
	Q.rear = (Q.rear + 1) % MAXQSIZE;
	return OK;
}

出队(不在老师给考试的范围内):

Status DeQueue(SqQueue &Q, QElemType &e){
//
	if( Q.rear == Q.front ){
		return ERROR;
	}
	e = Q.base[Q.front];
	Q.front = (Q.front + 1) % MAXQSIZE;
	return OK;
}

8.顺序栈的出栈算法 p47

Status Pop(SqStack &S, SElemType &e){
//栈不为空,则删除 S 的栈顶元素
	if(S.top == S.base){
		return ERROR;
	}
	e = * --S.top;
	return OK;
}

知识点

chap 1 绪论

基本概念和术语

  • 数据:data 所有能输入到计算机中并被计算机程序处理的符号的总称。
  • 数据元素:data element 是数据基本单位,一个数据元素可由若干数据项 data item 组成,数据项数据不可分割最小单位
  • 数据对象:data object 是性质相同的数据元素集合,是数据的一个子集
  • 数据结构:data structure 是相互之间存在一种或多种特定关系数据元素集合
    数据元素相互之间的关系称为结构 structure。根据数据元素之间关系的不同特性,通常有以下4类基本结构:
    • 集合:结构中的数据元素之间除了“同属于一个集合”的关系外,别无其它关系。
    • 线性结构:结构中的数据元素之间存在一个对一个的关系。
    • 树形结构:结构中的数据元素之间存在一个对多个的关系。
    • 图状结构 or 网状结构:结构中的数据元素之间存在多个对多个的关系。

结构定义中的“关系”描述的是数据元素之间的逻辑关系

衡量一个算法好坏的量度:

  • 时间复杂度:衡量算法执行的时间量级。
  • 空间复杂度:衡量算法的数据结构所占存储以及大量的附加存储。
  • 算法的其他性能:

chap 2 线性表

线性表的顺序表示:用一组地址连续的存储单元依次存储线性表的数据元素。
LOC(ai)=LOC(a1) + (i-1) * L
元素在计算机内“物理位置相邻”来表示线性表数据元素之间的逻辑关系
只要确定了存储线性表起始位置线性表任一数据元素都可以随机存取,所以线性表的顺序存储结构是一种随机存取存储结构

chap 3 栈

stack 是限定仅在表尾进行插入或删除操作的线性表表尾栈顶(top),表头栈底(bottom)。
遵循后进先出原则。可类比铁路调度站。

  • base栈底指针:
  • top栈顶指针:
    top = base;可以作为栈空的标记。非空栈的栈顶指针始终在栈顶元素的下一个位置上。
  • stacksize已分配的存储空间

条件:

  • 栈满条件:S.top - S.base >= S.stacksize
  • 栈空条件:S.top == S.base

chap 3 队列

队列:
queue 是一种先进先出线性表
它只允许在表的一端进行插入,而在另一端删除元素。这和我们日常生活中的排队是一致的。
在队列中,允许插入到一端叫做队尾 rear,允许删除的一端称为队头 front

循环队列:

  • front队列头指针:删除头元素时,头指针 +1,头指针始终指向队头元素
  • rear队列尾指针:插入尾元素时,尾指针 +1,尾指针始终指向队尾元素下一个位置

只凭 Q.front == Q.rear 无法判断队列空间是“空”还是“满”。
处理方法:少用一个元素空间,约定以 “front 在 rear 的下一位置上” 作为队列呈“满”状态的标志。

  • 队满条件:(Q.rear + 1) % MAXQSIZE == Q.front
  • 队空条件:Q.front == Q.rear

chap 6 树和二叉树

树的定义

树型结构非线性数据结构是以分支关系定义的层次结构。
树的结点包含一个数据元素及若干指向其子树的分支结点拥有的子树数成为节点的度(Degree)。

  • 度为 0 的结点称为叶子结点(Leaf)终端结点
  • 度不为 0 的结点称为分支节点非终端节点

分支结点根结点都是内部节点
树的度是树内各结点的度最大值

结点的层次(Level)从根开始定义起,根为第一层,根的孩子为第二层。
树中结点的最大层次称为树的深度

森林(Forest)是 m 棵互不相交的树的集合。对树中每个结点而言,其子树的集合即为森林 。

二叉树

二叉树的性质:

  • 在二叉树的第 i 层上,至多有 2i-1 个结点。
  • 深度为 k 的二叉树,至多有 2k-1 个结点。
  • 任何一颗二叉树,如果叶子节点数 = n0度为 2 的结点数 = n2 ,则 n0 = n2 + 1
    证明步骤:
    • 结点总数:n = n0 +n1 +n2
    • 分支数:B = n - 1B = n1 + 2n2

满二叉树:深度为 k 且有 2k-1 个结点的二叉树。
特点:每一层上的结点数都是最大节点数。

完全二叉树:深度为 k ,有 n 个节点,其每一个结点都与深度为 k 的满二叉树中编号从 1 至 n 的结点一一对应的二叉树。
特点:叶子结点只可能在层次最大的两层上出现;对任一结点,若其右分支下的子孙的最大层次为 j,则其左分支下的子孙的最大层次必为 j 或 j+1。

  • 具有 n 个结点的完全二叉树的深度为 (log2n) +1
  • 完全二叉树 子结点/2=双亲结点;双亲结点为 i ,则左孩子结点为 2i ,右孩子结点为 2i+1 。

二叉树的存储结构:

  • 顺序存储结构
  • 链式存储结构:
    二叉链表:n+1个空链域,n-1个非空链域。(总共 2n)
    三叉链表:n+2个空链域,2n-2个非空链域。(总共 3n)

森林

二叉树都可以用二叉链表作为存储结构。则通过二叉链表作为媒介,可导出二叉树之间的一个对应关系
也就是说,给定一棵,可以找到唯一的一棵二叉树与之对应。

chap 9 静态查找

通常以“其关键字给定值进行过比较的记录个数平均值”作为衡量查找算法好坏的依据。
等概率下顺序查找的平均查找长度:ASL = (n+1)/2

顺序表的查找:

  • 优点:算法简单,适应面广。对表的结构无任何要求,无论记录是否按关键字有序均可应用。
  • 缺点:平均查找长度较大,特别是当n很大时,查找效率较低。

有序表的查找:(折半查找)

  • low
  • mid = (low + high) / 2
  • high
  1. 折半查找过程:以处于区间中间位置记录关键字给定值比较,若相等,则查找成功,若不等,则缩小范围。
  2. 性能分析:
    折半查找过程可以用二叉树叙述,也叫判定树
    ∵ 折半查找在查找成功时,进行比较的关键字个数最多不超过树的深度h
    ∵ 而具有n个结点的判定树的深度为 h=(log2n)+1
    ∴ 折半查找法在查找成功时,和给定值进行比较的关键字个数至多为 h=(log2n)+1
  3. 折半查找的平均查找长度:
    ASLbs = log2(n+1) - 1
  4. 优缺点分析:
    优点:折半查找的效率比顺序查找高。
    缺点:只适用于有序表,且限于顺序存储结构。对线性链表无法有效的进行折半查找。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值