Upload
myles-tucker
View
38
Download
7
Embed Size (px)
DESCRIPTION
数据结构. 辅导教师 倪政林. 参考学习站点 : 自考网首页 : http://student.zjzk.cn/course_ware/ data_structure/web/main.htm 天极 yesky : http://www.yesky.com/SoftChannel/ 72348977504190464/20031118/1745923.shtml 维 C 世界 (C 版 ):http://www.vcok.com/class/ - PowerPoint PPT Presentation
Citation preview
数据结构数据结构
辅导教师 倪政林辅导教师 倪政林
参考学习站点 :
自考网首页 : http://student.zjzk.cn/course_ware/ data_structure/web/main.htm 天极 yesky : http://www.yesky.com/SoftChannel/ 72348977504190464/20031118/1745923.shtml 维 C 世界 (C 版 ):http://www.vcok.com/class/ index.asp?classid=9
数据结构第一章 绪论第二章 线性表第三章 稀疏矩阵和广义表第四章 栈和队列第五章 树和二叉树第六章 二叉树的应用第七章 图第八章 查找第九章 排序
二叉树的应用二叉树的应用二叉搜索树二叉搜索树堆堆 哈夫夫曼
6.1 6.1 二叉搜索树二叉搜索树
11 .定义.定义
22 .查找算法及性能的分析.查找算法及性能的分析
33 .插入算法.插入算法
44 .删除算法.删除算法
11 .定义.定义又称二叉排序树又称二叉排序树 ,, 它或是一棵空树它或是一棵空树 ,, 或者是具有如下或者是具有如下特点的非空二叉树特点的非空二叉树 ::(1)(1) 若它是左子树非空若它是左子树非空 ,, 则左子树上所有结点的关键字则左子树上所有结点的关键字均小于根结点的关键字均小于根结点的关键字 ;;(2)(2) 若它的右子树非空若它的右子树非空 ,, 则右子树则右子树上所有结点的关键字均大于上所有结点的关键字均大于根结点的关键字根结点的关键字 ;;(3)(3) 左、右子树又各是左、右子树又各是一棵二叉搜索树。一棵二叉搜索树。
30
15 52
74
63
12 23
2618
30
15 52
74
63
12 23
2618
中序是一个有序的结点序列。
性质 :
中序序列是什么
12, 15, 18, 23, 26, 30, 52, 63, 74
二叉链表作为二叉搜索树的二叉链表作为二叉搜索树的存储结构 存储结构
struct BTreeNode {
ElemType data;
BTreeNode * left;
BTreeNode * right;
};
22 .查找算法.查找算法A. 算法设计 :
Bool find (Btreenode * bst, elemtype& item){if (bst == null) return false;Else {if (item== Bst->data) {item = bst->data; return true;} else if (item < bst->data) return find(bst->left,item); else return find(bst->right,item); }}
B. 算法分析 :
最好 : 最坏 : 一般 :
30
15 52
74
63
12 23
2618
O(log2n)O(n)O(log2n)
思考题 :为什么会出现三种不同的复杂度
答案 : 最好的条件 : 理想平衡二叉树 最坏的条件 : 单支树 ( 线性表 ) 平均的条件 : 近似平衡二叉树
•“插入”操作在查找不成功不成功时才 进行;
3. 二叉搜索树的插入算法
•若二叉搜索树为空树,则新插入的结点为根结点根结点;否则,新插入的结点必为一个叶子结点叶子结点,其插入位置由查找过程得到。
30
15 52
74
63
12 23
2618
1 .如何插入 15 ?
2 .如何插入 81 、 14 ? 插入的结点具有 什么特点?
8114
答:都是叶子结点。
插入算法设计插入算法设计
Void insert(btreenode * bst,Void insert(btreenode * bst, const elemtype item)const elemtype item){if(bst == null){if(bst == null) {btreenode* P=new btreenode;{btreenode* P=new btreenode; p->data = item;p->data = item; p->left =p->right =null;p->left =p->right =null; bst = p;}bst = p;} else if ( item < bst->data )else if ( item < bst->data ) insert(bst->left,item);insert(bst->left,item); else insert(Bst->right,item);else insert(Bst->right,item);}}
( 1)被删除的结点是叶子;( 2)被删除的结点只有左子树 或者只有右子树;( 3)被删除的结点既有左子树, 也有右子树。
4. 二叉搜索树的删除算法可分三种情况讨论:
( 1 )被删除的结点是 : 叶子结点叶子结点
其双亲结点相应指针域改为“空空”
A
p
B
p
S = p->left; p->left = null ; delete(s); /S = p->right; p->left = null ; delete(s);
S S
( 2 )被删除的结点只有单支子树
其双亲结点的相应指针域改为 “指向被删除结点的左子树或 右子树”。
A
p
AA .右子树为空只需重接它的左子树.右子树为空只需重接它的左子树s=p->left; p->left =q ; delete(s);
q
s=p->right; p->right=q ; delete(s);
q
SS
B
p
BB .左子树为空只需重接它的右子.左子树为空只需重接它的右子
树树s=p->left; p->left =q ; delete(s);
s=p->right; p->right=q ; delete(s);
S S
A
p
q
B
p
q
( 3 )被删除的结点有左右子树
被删结点前驱结点
第一种方法:其右了树接到其第一前驱的右边,左子树接到其父结点的下边。
第一前驱:左子树中“最右下最右下”的结点 (左指针可能不为空)
30
15 52
74
63
12 23
2618
30
15 52
74
63
12 18
21
2628
1311
28
13
21
11
调整前 调整后
待删结点
第二种方法:把其中序前驱结点的值赋给该结点,删除前驱结点并把其左子树链到前驱所在的位置即可。
注:右子树中“最左下最左下”的结点 左指针可能不为空。
30
15 52
74
63
12 23
2618
30
14 52
74
63
12 23
2618
28
1411
28
13
13
11
调整前 调整后
待删结点
6.2 堆小根堆:若根结点存在左孩子,则根值小于左孩子值;若根有右孩子,则根值小于右孩子;左右孩子又是一个堆。大根堆相反。
18
26 35
6073 48
74
53 42
203525 36
2218小根堆 大根堆
图例
如何“建堆”?如何“建堆”?
两个问题 :
如何“筛选”?如何“筛选”?完全二叉树完全二叉树
调整为堆调整为堆
堆是满足下列性质的数列堆是满足下列性质的数列 {r{r11, r, r22, …, … ,, rrnn}} ::
或
12
2
ii
ii
rr
rr
12
2
ii
ii
rr
rr
( 小顶堆 ) ( 大顶堆 )
对于完全二叉树对于完全二叉树 r2i 是 ri 的左孩子r2i+1 是 ri 的右孩子
堆的存储结构--顺序存储(还有链式)
Struct Heap{elemtype heap[maxsize];int size;}插入得法(小根堆):Void insertheap(heap&hbt, const elemtype item){hbt.heap[hbt.size]=item;Hbt.size++; elemtype x=item; int i=hbt.size-1;While(I != 0) {int j=|| (i-1)/2 || ; if (x>=hbt.heap[j]) break; hbt.heap[i]=hbt.heap[j]; i=j;}Hbt.heap[i]=x;}
最最小小堆堆的的向向上上调调整整
图例
删除小根堆顶点的算法:Elemtype deleheap(heap& hbt){if(hbt.size==0){cerr<<“heap is null !”<<endl; exit(1);}Elemtype temp=hbt.heap[0];Hbt.size - - ; if (hbt.size==0) return temp;Elemtype x = hbt.heap[hbt.size];Int i=0; int j=2*i+1;While(j<=hbt.size-1){if (j < hbt.size-1 && hbt.heap[j] > hbt.heap[j+1] ) j++;If(x <= hbt.heap[j]) break;Hbt.heap[i] = hbt.heap[j];i=j; j=2*i+1;}Hbt.heap[i]=x; return temp;}
26
60 35
73 48
26
48 35
73 60
18
26 35
6073 48
60
26 35
6073 48
第一 第二
第三 第四
建堆实例:Void main(){int a[8]={23,56,40,62,38,55,10,16};Heap b; initheap(b); int I,x;For(i=0;i<8;i++) insert(b,a[i];While(!heapempty(b)){x=deleteheap(b);Cout<<x;If(!heapempty(b)) cout<<‘,’;}Cout<<endl;}
自下向上逐步调整为最小堆
图例图例
哈夫曼树哈夫曼树
• 最优树的定义• 如何构造最优树
最优树的定义 / 哈夫曼树
9
5
24
1
2
3 3
WPL=9*1+5*2+4*3+2*3
概念 : 路径长度、带权路径长度
哈夫曼树的构造过程哈夫曼树的构造过程